Rollup merge of #121062 - RustyYato:f32-midpoint, r=the8472 · model-checking/verify-rust-std@380d9a3 (original) (raw)
`@@ -729,7 +729,7 @@ assume_usize_width! {
`
729
729
`}
`
730
730
``
731
731
`macro_rules! test_float {
`
732
``
`-
($modname: ident, fty:ty,fty: ty, fty:ty,inf: expr, neginf:expr,neginf: expr, neginf:expr,nan: expr, min:expr,min: expr, min:expr,max: expr, $min_pos: expr) => {
`
``
732
`+
($modname: ident, fty:ty,fty: ty, fty:ty,inf: expr, neginf:expr,neginf: expr, neginf:expr,nan: expr, min:expr,min: expr, min:expr,max: expr, minpos:expr,min_pos: expr, minpos:expr,max_exp:expr) => {
`
733
733
`mod $modname {
`
734
734
` #[test]
`
735
735
`fn min() {
`
`@@ -880,6 +880,27 @@ macro_rules! test_float {
`
880
880
` assert!(($nan as $fty).midpoint(1.0).is_nan());
`
881
881
` assert!((1.0 as fty).midpoint(fty).midpoint(fty).midpoint(nan).is_nan());
`
882
882
` assert!(($nan as fty).midpoint(fty).midpoint(fty).midpoint(nan).is_nan());
`
``
883
+
``
884
`+
// test if large differences in magnitude are still correctly computed.
`
``
885
`+
// NOTE: that because of how small x and y are, x + y can never overflow
`
``
886
`+
// so (x + y) / 2.0 is always correct
`
``
887
`` +
// in particular, 2.pow(i)
will never be at the max exponent, so it could
``
``
888
`+
// be safely doubled, while j is significantly smaller.
`
``
889
`+
for i in maxexp.saturatingsub(64)..max_exp.saturating_sub(64)..maxexp.saturatingsub(64)..max_exp {
`
``
890
`+
for j in 0..64u8 {
`
``
891
`+
let large = <$fty>::from(2.0f32).powi(i);
`
``
892
`+
// a much smaller number, such that there is no chance of overflow to test
`
``
893
`+
// potential double rounding in midpoint's implementation.
`
``
894
`+
let small = <$fty>::from(2.0f32).powi($max_exp - 1)
`
``
895
`+
- <$fty>::EPSILON
`
``
896
`+
- <$fty>::from(j);
`
``
897
+
``
898
`+
let naive = (large + small) / 2.0;
`
``
899
`+
let midpoint = large.midpoint(small);
`
``
900
+
``
901
`+
assert_eq!(naive, midpoint);
`
``
902
`+
}
`
``
903
`+
}
`
883
904
`}
`
884
905
` #[test]
`
885
906
`fn rem_euclid() {
`
`@@ -912,7 +933,8 @@ test_float!(
`
912
933
`f32::NAN,
`
913
934
`f32::MIN,
`
914
935
`f32::MAX,
`
915
``
`-
f32::MIN_POSITIVE
`
``
936
`+
f32::MIN_POSITIVE,
`
``
937
`+
f32::MAX_EXP
`
916
938
`);
`
917
939
`test_float!(
`
918
940
`f64,
`
`@@ -922,5 +944,6 @@ test_float!(
`
922
944
`f64::NAN,
`
923
945
`f64::MIN,
`
924
946
`f64::MAX,
`
925
``
`-
f64::MIN_POSITIVE
`
``
947
`+
f64::MIN_POSITIVE,
`
``
948
`+
f64::MAX_EXP
`
926
949
`);
`