about summary refs log tree commit diff
path: root/library
diff options
context:
space:
mode:
authorRoger Curley <rocurley@gmail.com>2025-08-03 23:08:36 -0400
committerRoger Curley <rocurley@gmail.com>2025-08-07 22:06:56 -0400
commitf51f68b49ae63c44f9be8b3e2a5774e177cdc5ed (patch)
tree854c84fa32dbf66f5171141f8ea4d0be14206e54 /library
parent71973fcbdb1c6681b603c675bb3177724ae2e403 (diff)
downloadrust-f51f68b49ae63c44f9be8b3e2a5774e177cdc5ed.tar.gz
rust-f51f68b49ae63c44f9be8b3e2a5774e177cdc5ed.zip
Consolidate test_next_up
Note that the behaviour of the f128 test is slightly changed to use the
same nan mask as is used in test_float_bits_conv, which is the behaviour
used by f16,f32,and f64.
Diffstat (limited to 'library')
-rw-r--r--library/coretests/tests/floats/f128.rs30
-rw-r--r--library/coretests/tests/floats/f16.rs30
-rw-r--r--library/coretests/tests/floats/f32.rs30
-rw-r--r--library/coretests/tests/floats/f64.rs29
-rw-r--r--library/coretests/tests/floats/mod.rs69
5 files changed, 69 insertions, 119 deletions
diff --git a/library/coretests/tests/floats/f128.rs b/library/coretests/tests/floats/f128.rs
index d3f8e8ef1d2..71ca2abf303 100644
--- a/library/coretests/tests/floats/f128.rs
+++ b/library/coretests/tests/floats/f128.rs
@@ -40,36 +40,6 @@ const NAN_MASK2: u128 = 0x00005555555555555555555555555555;
 // the intrinsics.
 
 #[test]
-fn test_next_up() {
-    let tiny = f128::from_bits(TINY_BITS);
-    let tiny_up = f128::from_bits(TINY_UP_BITS);
-    let max_down = f128::from_bits(MAX_DOWN_BITS);
-    let largest_subnormal = f128::from_bits(LARGEST_SUBNORMAL_BITS);
-    let smallest_normal = f128::from_bits(SMALLEST_NORMAL_BITS);
-    assert_biteq!(f128::NEG_INFINITY.next_up(), f128::MIN);
-    assert_biteq!(f128::MIN.next_up(), -max_down);
-    assert_biteq!((-1.0 - f128::EPSILON).next_up(), -1.0f128);
-    assert_biteq!((-smallest_normal).next_up(), -largest_subnormal);
-    assert_biteq!((-tiny_up).next_up(), -tiny);
-    assert_biteq!((-tiny).next_up(), -0.0f128);
-    assert_biteq!((-0.0f128).next_up(), tiny);
-    assert_biteq!(0.0f128.next_up(), tiny);
-    assert_biteq!(tiny.next_up(), tiny_up);
-    assert_biteq!(largest_subnormal.next_up(), smallest_normal);
-    assert_biteq!(1.0f128.next_up(), 1.0 + f128::EPSILON);
-    assert_biteq!(f128::MAX.next_up(), f128::INFINITY);
-    assert_biteq!(f128::INFINITY.next_up(), f128::INFINITY);
-
-    // Check that NaNs roundtrip.
-    let nan0 = f128::NAN;
-    let nan1 = f128::from_bits(f128::NAN.to_bits() ^ 0x002a_aaaa);
-    let nan2 = f128::from_bits(f128::NAN.to_bits() ^ 0x0055_5555);
-    assert_biteq!(nan0.next_up(), nan0);
-    assert_biteq!(nan1.next_up(), nan1);
-    assert_biteq!(nan2.next_up(), nan2);
-}
-
-#[test]
 fn test_next_down() {
     let tiny = f128::from_bits(TINY_BITS);
     let tiny_up = f128::from_bits(TINY_UP_BITS);
diff --git a/library/coretests/tests/floats/f16.rs b/library/coretests/tests/floats/f16.rs
index db46bff1571..e739e6fd0c9 100644
--- a/library/coretests/tests/floats/f16.rs
+++ b/library/coretests/tests/floats/f16.rs
@@ -46,36 +46,6 @@ const NAN_MASK2: u16 = 0x0155;
 // the intrinsics.
 
 #[test]
-fn test_next_up() {
-    let tiny = f16::from_bits(TINY_BITS);
-    let tiny_up = f16::from_bits(TINY_UP_BITS);
-    let max_down = f16::from_bits(MAX_DOWN_BITS);
-    let largest_subnormal = f16::from_bits(LARGEST_SUBNORMAL_BITS);
-    let smallest_normal = f16::from_bits(SMALLEST_NORMAL_BITS);
-    assert_biteq!(f16::NEG_INFINITY.next_up(), f16::MIN);
-    assert_biteq!(f16::MIN.next_up(), -max_down);
-    assert_biteq!((-1.0 - f16::EPSILON).next_up(), -1.0f16);
-    assert_biteq!((-smallest_normal).next_up(), -largest_subnormal);
-    assert_biteq!((-tiny_up).next_up(), -tiny);
-    assert_biteq!((-tiny).next_up(), -0.0f16);
-    assert_biteq!((-0.0f16).next_up(), tiny);
-    assert_biteq!(0.0f16.next_up(), tiny);
-    assert_biteq!(tiny.next_up(), tiny_up);
-    assert_biteq!(largest_subnormal.next_up(), smallest_normal);
-    assert_biteq!(1.0f16.next_up(), 1.0 + f16::EPSILON);
-    assert_biteq!(f16::MAX.next_up(), f16::INFINITY);
-    assert_biteq!(f16::INFINITY.next_up(), f16::INFINITY);
-
-    // Check that NaNs roundtrip.
-    let nan0 = f16::NAN;
-    let nan1 = f16::from_bits(f16::NAN.to_bits() ^ NAN_MASK1);
-    let nan2 = f16::from_bits(f16::NAN.to_bits() ^ NAN_MASK2);
-    assert_biteq!(nan0.next_up(), nan0);
-    assert_biteq!(nan1.next_up(), nan1);
-    assert_biteq!(nan2.next_up(), nan2);
-}
-
-#[test]
 fn test_next_down() {
     let tiny = f16::from_bits(TINY_BITS);
     let tiny_up = f16::from_bits(TINY_UP_BITS);
diff --git a/library/coretests/tests/floats/f32.rs b/library/coretests/tests/floats/f32.rs
index 6994e813408..9612660108c 100644
--- a/library/coretests/tests/floats/f32.rs
+++ b/library/coretests/tests/floats/f32.rs
@@ -30,36 +30,6 @@ const NAN_MASK2: u32 = 0x0055_5555;
 const APPROX_DELTA: f32 = if cfg!(miri) { 1e-4 } else { 1e-6 };
 
 #[test]
-fn test_next_up() {
-    let tiny = f32::from_bits(TINY_BITS);
-    let tiny_up = f32::from_bits(TINY_UP_BITS);
-    let max_down = f32::from_bits(MAX_DOWN_BITS);
-    let largest_subnormal = f32::from_bits(LARGEST_SUBNORMAL_BITS);
-    let smallest_normal = f32::from_bits(SMALLEST_NORMAL_BITS);
-    assert_biteq!(f32::NEG_INFINITY.next_up(), f32::MIN);
-    assert_biteq!(f32::MIN.next_up(), -max_down);
-    assert_biteq!((-1.0f32 - f32::EPSILON).next_up(), -1.0f32);
-    assert_biteq!((-smallest_normal).next_up(), -largest_subnormal);
-    assert_biteq!((-tiny_up).next_up(), -tiny);
-    assert_biteq!((-tiny).next_up(), -0.0f32);
-    assert_biteq!((-0.0f32).next_up(), tiny);
-    assert_biteq!(0.0f32.next_up(), tiny);
-    assert_biteq!(tiny.next_up(), tiny_up);
-    assert_biteq!(largest_subnormal.next_up(), smallest_normal);
-    assert_biteq!(1.0f32.next_up(), 1.0 + f32::EPSILON);
-    assert_biteq!(f32::MAX.next_up(), f32::INFINITY);
-    assert_biteq!(f32::INFINITY.next_up(), f32::INFINITY);
-
-    // Check that NaNs roundtrip.
-    let nan0 = f32::NAN;
-    let nan1 = f32::from_bits(f32::NAN.to_bits() ^ NAN_MASK1);
-    let nan2 = f32::from_bits(f32::NAN.to_bits() ^ NAN_MASK2);
-    assert_biteq!(nan0.next_up(), nan0);
-    assert_biteq!(nan1.next_up(), nan1);
-    assert_biteq!(nan2.next_up(), nan2);
-}
-
-#[test]
 fn test_next_down() {
     let tiny = f32::from_bits(TINY_BITS);
     let tiny_up = f32::from_bits(TINY_UP_BITS);
diff --git a/library/coretests/tests/floats/f64.rs b/library/coretests/tests/floats/f64.rs
index 6b5fc8f69c3..cd535da681d 100644
--- a/library/coretests/tests/floats/f64.rs
+++ b/library/coretests/tests/floats/f64.rs
@@ -25,35 +25,6 @@ const NAN_MASK1: u64 = 0x000a_aaaa_aaaa_aaaa;
 const NAN_MASK2: u64 = 0x0005_5555_5555_5555;
 
 #[test]
-fn test_next_up() {
-    let tiny = f64::from_bits(TINY_BITS);
-    let tiny_up = f64::from_bits(TINY_UP_BITS);
-    let max_down = f64::from_bits(MAX_DOWN_BITS);
-    let largest_subnormal = f64::from_bits(LARGEST_SUBNORMAL_BITS);
-    let smallest_normal = f64::from_bits(SMALLEST_NORMAL_BITS);
-    assert_biteq!(f64::NEG_INFINITY.next_up(), f64::MIN);
-    assert_biteq!(f64::MIN.next_up(), -max_down);
-    assert_biteq!((-1.0 - f64::EPSILON).next_up(), -1.0f64);
-    assert_biteq!((-smallest_normal).next_up(), -largest_subnormal);
-    assert_biteq!((-tiny_up).next_up(), -tiny);
-    assert_biteq!((-tiny).next_up(), -0.0f64);
-    assert_biteq!((-0.0f64).next_up(), tiny);
-    assert_biteq!(0.0f64.next_up(), tiny);
-    assert_biteq!(tiny.next_up(), tiny_up);
-    assert_biteq!(largest_subnormal.next_up(), smallest_normal);
-    assert_biteq!(1.0f64.next_up(), 1.0 + f64::EPSILON);
-    assert_biteq!(f64::MAX.next_up(), f64::INFINITY);
-    assert_biteq!(f64::INFINITY.next_up(), f64::INFINITY);
-
-    let nan0 = f64::NAN;
-    let nan1 = f64::from_bits(f64::NAN.to_bits() ^ NAN_MASK1);
-    let nan2 = f64::from_bits(f64::NAN.to_bits() ^ NAN_MASK2);
-    assert_biteq!(nan0.next_up(), nan0);
-    assert_biteq!(nan1.next_up(), nan1);
-    assert_biteq!(nan2.next_up(), nan2);
-}
-
-#[test]
 fn test_next_down() {
     let tiny = f64::from_bits(TINY_BITS);
     let tiny_up = f64::from_bits(TINY_UP_BITS);
diff --git a/library/coretests/tests/floats/mod.rs b/library/coretests/tests/floats/mod.rs
index b8600b30fd7..beb016ce4d0 100644
--- a/library/coretests/tests/floats/mod.rs
+++ b/library/coretests/tests/floats/mod.rs
@@ -2,34 +2,70 @@ use std::num::FpCategory as Fp;
 use std::ops::{Add, Div, Mul, Rem, Sub};
 
 trait TestableFloat {
+    /// Unsigned int with the same size, for converting to/from bits.
+    type Int;
     /// Set the default tolerance for float comparison based on the type.
     const APPROX: Self;
     const MIN_POSITIVE_NORMAL: Self;
     const MAX_SUBNORMAL: Self;
+    /// Smallest number
+    const TINY: Self;
+    /// Next smallest number
+    const TINY_UP: Self;
+    /// Exponent = 0b11...10, Significand 0b1111..10. Min val > 0
+    const MAX_DOWN: Self;
+    /// First pattern over the mantissa
+    const NAN_MASK1: Self::Int;
+    /// Second pattern over the mantissa
+    const NAN_MASK2: Self::Int;
 }
 
 impl TestableFloat for f16 {
+    type Int = u16;
     const APPROX: Self = 1e-3;
     const MIN_POSITIVE_NORMAL: Self = Self::MIN_POSITIVE;
     const MAX_SUBNORMAL: Self = Self::MIN_POSITIVE.next_down();
+    const TINY: Self = Self::from_bits(0x1);
+    const TINY_UP: Self = Self::from_bits(0x2);
+    const MAX_DOWN: Self = Self::from_bits(0x7bfe);
+    const NAN_MASK1: Self::Int = 0x02aa;
+    const NAN_MASK2: Self::Int = 0x0155;
 }
 
 impl TestableFloat for f32 {
+    type Int = u32;
     const APPROX: Self = 1e-6;
     const MIN_POSITIVE_NORMAL: Self = Self::MIN_POSITIVE;
     const MAX_SUBNORMAL: Self = Self::MIN_POSITIVE.next_down();
+    const TINY: Self = Self::from_bits(0x1);
+    const TINY_UP: Self = Self::from_bits(0x2);
+    const MAX_DOWN: Self = Self::from_bits(0x7f7f_fffe);
+    const NAN_MASK1: Self::Int = 0x002a_aaaa;
+    const NAN_MASK2: Self::Int = 0x0055_5555;
 }
 
 impl TestableFloat for f64 {
+    type Int = u64;
     const APPROX: Self = 1e-6;
     const MIN_POSITIVE_NORMAL: Self = Self::MIN_POSITIVE;
     const MAX_SUBNORMAL: Self = Self::MIN_POSITIVE.next_down();
+    const TINY: Self = Self::from_bits(0x1);
+    const TINY_UP: Self = Self::from_bits(0x2);
+    const MAX_DOWN: Self = Self::from_bits(0x7fef_ffff_ffff_fffe);
+    const NAN_MASK1: Self::Int = 0x000a_aaaa_aaaa_aaaa;
+    const NAN_MASK2: Self::Int = 0x0005_5555_5555_5555;
 }
 
 impl TestableFloat for f128 {
+    type Int = u128;
     const APPROX: Self = 1e-9;
     const MIN_POSITIVE_NORMAL: Self = Self::MIN_POSITIVE;
     const MAX_SUBNORMAL: Self = Self::MIN_POSITIVE.next_down();
+    const TINY: Self = Self::from_bits(0x1);
+    const TINY_UP: Self = Self::from_bits(0x2);
+    const MAX_DOWN: Self = Self::from_bits(0x7ffefffffffffffffffffffffffffffe);
+    const NAN_MASK1: Self::Int = 0x0000aaaaaaaaaaaaaaaaaaaaaaaaaaaa;
+    const NAN_MASK2: Self::Int = 0x00005555555555555555555555555555;
 }
 
 /// Determine the tolerance for values of the argument type.
@@ -1019,3 +1055,36 @@ float_test! {
         assert!((-Float::NAN).is_sign_negative());
     }
 }
+
+float_test! {
+    name: next_up,
+    attrs: {
+        f16: #[cfg(any(miri, target_has_reliable_f16))],
+        f128: #[cfg(any(miri, target_has_reliable_f128))],
+    },
+    test<Float> {
+        let one: Float = 1.0;
+        let zero: Float = 0.0;
+        assert_biteq!(Float::NEG_INFINITY.next_up(), Float::MIN);
+        assert_biteq!(Float::MIN.next_up(), -Float::MAX_DOWN);
+        assert_biteq!((-one - Float::EPSILON).next_up(), -one);
+        assert_biteq!((-Float::MIN_POSITIVE_NORMAL).next_up(), -Float::MAX_SUBNORMAL);
+        assert_biteq!((-Float::TINY_UP).next_up(), -Float::TINY);
+        assert_biteq!((-Float::TINY).next_up(), -zero);
+        assert_biteq!((-zero).next_up(), Float::TINY);
+        assert_biteq!(zero.next_up(), Float::TINY);
+        assert_biteq!(Float::TINY.next_up(), Float::TINY_UP);
+        assert_biteq!(Float::MAX_SUBNORMAL.next_up(), Float::MIN_POSITIVE_NORMAL);
+        assert_biteq!(one.next_up(), 1.0 + Float::EPSILON);
+        assert_biteq!(Float::MAX.next_up(), Float::INFINITY);
+        assert_biteq!(Float::INFINITY.next_up(), Float::INFINITY);
+
+        // Check that NaNs roundtrip.
+        let nan0 = Float::NAN;
+        let nan1 = Float::from_bits(Float::NAN.to_bits() ^ Float::NAN_MASK1);
+        let nan2 = Float::from_bits(Float::NAN.to_bits() ^ Float::NAN_MASK2);
+        assert_biteq!(nan0.next_up(), nan0);
+        assert_biteq!(nan1.next_up(), nan1);
+        assert_biteq!(nan2.next_up(), nan2);
+    }
+}