Skip to content

Commit 1b4fc40

Browse files
committed
make test generic over f32/f64
1 parent aa9ea63 commit 1b4fc40

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

library/core/src/num/f32.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1026,6 +1026,7 @@ impl f32 {
10261026
// whitelist the faster implementation to targets that have known good 64-bit float
10271027
// implementations. Falling back to the branchy code on targets that don't have
10281028
// 64-bit hardware floats or buggy implementations.
1029+
// see: https://github.com/rust-lang/rust/pull/121062#issuecomment-2123408114
10291030
((f64::from(self) + f64::from(other)) / 2.0) as f32
10301031
} else {
10311032
const LO: f32 = f32::MIN_POSITIVE * 2.;

library/core/tests/num/mod.rs

+19-7
Original file line numberDiff line numberDiff line change
@@ -719,7 +719,7 @@ assume_usize_width! {
719719
}
720720

721721
macro_rules! test_float {
722-
($modname: ident, $fty: ty, $inf: expr, $neginf: expr, $nan: expr, $min: expr, $max: expr, $min_pos: expr) => {
722+
($modname: ident, $fty: ty, $inf: expr, $neginf: expr, $nan: expr, $min: expr, $max: expr, $min_pos: expr, $max_exp:expr) => {
723723
mod $modname {
724724
#[test]
725725
fn min() {
@@ -874,11 +874,21 @@ macro_rules! test_float {
874874
// test if large differences in magnitude are still correctly computed.
875875
// NOTE: that because of how small x and y are, x + y can never overflow
876876
// so (x + y) / 2.0 is always correct
877-
for i in 64..128 {
877+
// in particular, `2.pow(i)` will never be at the max exponent, so it could
878+
// be safely doubled, while j is significantly smaller.
879+
for i in $max_exp.saturating_sub(64)..$max_exp {
878880
for j in 0..64u8 {
879-
let x = (2.0f32.powi(i) + f32::from(j)) / 2.0;
880-
let y = 2.0f32.powi(i).midpoint(f32::from(j));
881-
assert_eq!(x, y);
881+
let large = <$fty>::from(2.0f32).powi(i);
882+
// a much smaller number, such that there is no chance of overflow to test
883+
// potential double rounding in midpoint's implementation.
884+
let small = <$fty>::from(2.0f32).powi($max_exp - 1)
885+
* <$fty>::EPSILON
886+
* <$fty>::from(j);
887+
888+
let naive = (large + small) / 2.0;
889+
let midpoint = large.midpoint(small);
890+
891+
assert_eq!(naive, midpoint);
882892
}
883893
}
884894
}
@@ -913,7 +923,8 @@ test_float!(
913923
f32::NAN,
914924
f32::MIN,
915925
f32::MAX,
916-
f32::MIN_POSITIVE
926+
f32::MIN_POSITIVE,
927+
f32::MAX_EXP
917928
);
918929
test_float!(
919930
f64,
@@ -923,5 +934,6 @@ test_float!(
923934
f64::NAN,
924935
f64::MIN,
925936
f64::MAX,
926-
f64::MIN_POSITIVE
937+
f64::MIN_POSITIVE,
938+
f64::MAX_EXP
927939
);

0 commit comments

Comments
 (0)