about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTrevor Gross <tmgross@umich.edu>2025-02-25 06:06:18 +0000
committerTrevor Gross <tmgross@umich.edu>2025-05-14 14:29:58 +0000
commit2b9256e1c8454255441983446ca6bb63a6d8a199 (patch)
tree08a96045b9946c9cfa54246764572ae1d2bace40
parent48f3e63f709ec4a19fa2bdce33893fdc45006e46 (diff)
downloadrust-2b9256e1c8454255441983446ca6bb63a6d8a199.tar.gz
rust-2b9256e1c8454255441983446ca6bb63a6d8a199.zip
Move applicable float tests from `coretests` back to `std`
The previous commit moved all test files from `std` to `core` so git
understands the move. Not all functionality is actually testable in
`core`, however, so perform move the relevant portions back. Changes
from inherent to module methods is also done since this is the form of
math operations available in `core` (as `core_float_math`).
-rw-r--r--library/coretests/tests/floats/f128.rs287
-rw-r--r--library/coretests/tests/floats/f16.rs271
-rw-r--r--library/coretests/tests/floats/f32.rs390
-rw-r--r--library/coretests/tests/floats/f64.rs363
-rw-r--r--library/coretests/tests/floats/mod.rs4
-rw-r--r--library/coretests/tests/lib.rs6
-rw-r--r--library/std/tests/floats/f128.rs321
-rw-r--r--library/std/tests/floats/f16.rs300
-rw-r--r--library/std/tests/floats/f32.rs253
-rw-r--r--library/std/tests/floats/f64.rs249
-rw-r--r--library/std/tests/floats/lib.rs43
11 files changed, 1314 insertions, 1173 deletions
diff --git a/library/coretests/tests/floats/f128.rs b/library/coretests/tests/floats/f128.rs
index c2618f3b315..12cf651f03f 100644
--- a/library/coretests/tests/floats/f128.rs
+++ b/library/coretests/tests/floats/f128.rs
@@ -10,19 +10,13 @@ use std::ops::{Add, Div, Mul, Sub};
 
 // Note these tolerances make sense around zero, but not for more extreme exponents.
 
-/// For operations that are near exact, usually not involving math of different
-/// signs.
-const TOL_PRECISE: f128 = 1e-28;
-
 /// Default tolerances. Works for values that should be near precise but not exact. Roughly
 /// the precision carried by `100 * 100`.
 const TOL: f128 = 1e-12;
 
-/// Tolerances for math that is allowed to be imprecise, usually due to multiple chained
-/// operations.
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f128_math)]
-const TOL_IMPR: f128 = 1e-10;
+/// For operations that are near exact, usually not involving math of different
+/// signs.
+const TOL_PRECISE: f128 = 1e-28;
 
 /// Smallest number
 const TINY_BITS: u128 = 0x1;
@@ -500,8 +494,6 @@ fn test_recip() {
     assert_eq!(neg_inf.recip(), 0.0);
 }
 
-// Many math functions allow for less accurate results, so the next tolerance up is used
-
 #[test]
 #[cfg(not(miri))]
 #[cfg(target_has_reliable_f128_math)]
@@ -521,24 +513,6 @@ fn test_powi() {
 #[test]
 #[cfg(not(miri))]
 #[cfg(target_has_reliable_f128_math)]
-fn test_powf() {
-    let nan: f128 = f128::NAN;
-    let inf: f128 = f128::INFINITY;
-    let neg_inf: f128 = f128::NEG_INFINITY;
-    assert_eq!(1.0f128.powf(1.0), 1.0);
-    assert_approx_eq!(3.4f128.powf(4.5), 246.40818323761892815995637964326426756, TOL_IMPR);
-    assert_approx_eq!(2.7f128.powf(-3.2), 0.041652009108526178281070304373500889273, TOL_IMPR);
-    assert_approx_eq!((-3.1f128).powf(2.0), 9.6100000000000005506706202140776519387, TOL_IMPR);
-    assert_approx_eq!(5.9f128.powf(-2.0), 0.028727377190462507313100483690639638451, TOL_IMPR);
-    assert_eq!(8.3f128.powf(0.0), 1.0);
-    assert!(nan.powf(2.0).is_nan());
-    assert_eq!(inf.powf(2.0), inf);
-    assert_eq!(neg_inf.powf(3.0), neg_inf);
-}
-
-#[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f128_math)]
 fn test_sqrt_domain() {
     assert!(f128::NAN.sqrt().is_nan());
     assert!(f128::NEG_INFINITY.sqrt().is_nan());
@@ -550,111 +524,6 @@ fn test_sqrt_domain() {
 }
 
 #[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f128_math)]
-fn test_exp() {
-    assert_eq!(1.0, 0.0f128.exp());
-    assert_approx_eq!(consts::E, 1.0f128.exp(), TOL);
-    assert_approx_eq!(148.41315910257660342111558004055227962348775, 5.0f128.exp(), TOL);
-
-    let inf: f128 = f128::INFINITY;
-    let neg_inf: f128 = f128::NEG_INFINITY;
-    let nan: f128 = f128::NAN;
-    assert_eq!(inf, inf.exp());
-    assert_eq!(0.0, neg_inf.exp());
-    assert!(nan.exp().is_nan());
-}
-
-#[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f128_math)]
-fn test_exp2() {
-    assert_eq!(32.0, 5.0f128.exp2());
-    assert_eq!(1.0, 0.0f128.exp2());
-
-    let inf: f128 = f128::INFINITY;
-    let neg_inf: f128 = f128::NEG_INFINITY;
-    let nan: f128 = f128::NAN;
-    assert_eq!(inf, inf.exp2());
-    assert_eq!(0.0, neg_inf.exp2());
-    assert!(nan.exp2().is_nan());
-}
-
-#[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f128_math)]
-fn test_ln() {
-    let nan: f128 = f128::NAN;
-    let inf: f128 = f128::INFINITY;
-    let neg_inf: f128 = f128::NEG_INFINITY;
-    assert_approx_eq!(1.0f128.exp().ln(), 1.0, TOL);
-    assert!(nan.ln().is_nan());
-    assert_eq!(inf.ln(), inf);
-    assert!(neg_inf.ln().is_nan());
-    assert!((-2.3f128).ln().is_nan());
-    assert_eq!((-0.0f128).ln(), neg_inf);
-    assert_eq!(0.0f128.ln(), neg_inf);
-    assert_approx_eq!(4.0f128.ln(), 1.3862943611198906188344642429163531366, TOL);
-}
-
-#[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f128_math)]
-fn test_log() {
-    let nan: f128 = f128::NAN;
-    let inf: f128 = f128::INFINITY;
-    let neg_inf: f128 = f128::NEG_INFINITY;
-    assert_eq!(10.0f128.log(10.0), 1.0);
-    assert_approx_eq!(2.3f128.log(3.5), 0.66485771361478710036766645911922010272, TOL);
-    assert_eq!(1.0f128.exp().log(1.0f128.exp()), 1.0);
-    assert!(1.0f128.log(1.0).is_nan());
-    assert!(1.0f128.log(-13.9).is_nan());
-    assert!(nan.log(2.3).is_nan());
-    assert_eq!(inf.log(10.0), inf);
-    assert!(neg_inf.log(8.8).is_nan());
-    assert!((-2.3f128).log(0.1).is_nan());
-    assert_eq!((-0.0f128).log(2.0), neg_inf);
-    assert_eq!(0.0f128.log(7.0), neg_inf);
-}
-
-#[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f128_math)]
-fn test_log2() {
-    let nan: f128 = f128::NAN;
-    let inf: f128 = f128::INFINITY;
-    let neg_inf: f128 = f128::NEG_INFINITY;
-    assert_approx_eq!(10.0f128.log2(), 3.32192809488736234787031942948939017, TOL);
-    assert_approx_eq!(2.3f128.log2(), 1.2016338611696504130002982471978765921, TOL);
-    assert_approx_eq!(1.0f128.exp().log2(), 1.4426950408889634073599246810018921381, TOL);
-    assert!(nan.log2().is_nan());
-    assert_eq!(inf.log2(), inf);
-    assert!(neg_inf.log2().is_nan());
-    assert!((-2.3f128).log2().is_nan());
-    assert_eq!((-0.0f128).log2(), neg_inf);
-    assert_eq!(0.0f128.log2(), neg_inf);
-}
-
-#[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f128_math)]
-fn test_log10() {
-    let nan: f128 = f128::NAN;
-    let inf: f128 = f128::INFINITY;
-    let neg_inf: f128 = f128::NEG_INFINITY;
-    assert_eq!(10.0f128.log10(), 1.0);
-    assert_approx_eq!(2.3f128.log10(), 0.36172783601759284532595218865859309898, TOL);
-    assert_approx_eq!(1.0f128.exp().log10(), 0.43429448190325182765112891891660508222, TOL);
-    assert_eq!(1.0f128.log10(), 0.0);
-    assert!(nan.log10().is_nan());
-    assert_eq!(inf.log10(), inf);
-    assert!(neg_inf.log10().is_nan());
-    assert!((-2.3f128).log10().is_nan());
-    assert_eq!((-0.0f128).log10(), neg_inf);
-    assert_eq!(0.0f128.log10(), neg_inf);
-}
-
-#[test]
 fn test_to_degrees() {
     let pi: f128 = consts::PI;
     let nan: f128 = f128::NAN;
@@ -687,156 +556,6 @@ fn test_to_radians() {
 }
 
 #[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f128_math)]
-fn test_asinh() {
-    // Lower accuracy results are allowed, use increased tolerances
-    assert_eq!(0.0f128.asinh(), 0.0f128);
-    assert_eq!((-0.0f128).asinh(), -0.0f128);
-
-    let inf: f128 = f128::INFINITY;
-    let neg_inf: f128 = f128::NEG_INFINITY;
-    let nan: f128 = f128::NAN;
-    assert_eq!(inf.asinh(), inf);
-    assert_eq!(neg_inf.asinh(), neg_inf);
-    assert!(nan.asinh().is_nan());
-    assert!((-0.0f128).asinh().is_sign_negative());
-
-    // issue 63271
-    assert_approx_eq!(2.0f128.asinh(), 1.443635475178810342493276740273105f128, TOL_IMPR);
-    assert_approx_eq!((-2.0f128).asinh(), -1.443635475178810342493276740273105f128, TOL_IMPR);
-    // regression test for the catastrophic cancellation fixed in 72486
-    assert_approx_eq!(
-        (-67452098.07139316f128).asinh(),
-        -18.720075426274544393985484294000831757220,
-        TOL_IMPR
-    );
-
-    // test for low accuracy from issue 104548
-    assert_approx_eq!(60.0f128, 60.0f128.sinh().asinh(), TOL_IMPR);
-    // mul needed for approximate comparison to be meaningful
-    assert_approx_eq!(1.0f128, 1e-15f128.sinh().asinh() * 1e15f128, TOL_IMPR);
-}
-
-#[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f128_math)]
-fn test_acosh() {
-    assert_eq!(1.0f128.acosh(), 0.0f128);
-    assert!(0.999f128.acosh().is_nan());
-
-    let inf: f128 = f128::INFINITY;
-    let neg_inf: f128 = f128::NEG_INFINITY;
-    let nan: f128 = f128::NAN;
-    assert_eq!(inf.acosh(), inf);
-    assert!(neg_inf.acosh().is_nan());
-    assert!(nan.acosh().is_nan());
-    assert_approx_eq!(2.0f128.acosh(), 1.31695789692481670862504634730796844f128, TOL_IMPR);
-    assert_approx_eq!(3.0f128.acosh(), 1.76274717403908605046521864995958461f128, TOL_IMPR);
-
-    // test for low accuracy from issue 104548
-    assert_approx_eq!(60.0f128, 60.0f128.cosh().acosh(), TOL_IMPR);
-}
-
-#[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f128_math)]
-fn test_atanh() {
-    assert_eq!(0.0f128.atanh(), 0.0f128);
-    assert_eq!((-0.0f128).atanh(), -0.0f128);
-
-    let inf: f128 = f128::INFINITY;
-    let neg_inf: f128 = f128::NEG_INFINITY;
-    let nan: f128 = f128::NAN;
-    assert_eq!(1.0f128.atanh(), inf);
-    assert_eq!((-1.0f128).atanh(), neg_inf);
-    assert!(2f128.atanh().atanh().is_nan());
-    assert!((-2f128).atanh().atanh().is_nan());
-    assert!(inf.atanh().is_nan());
-    assert!(neg_inf.atanh().is_nan());
-    assert!(nan.atanh().is_nan());
-    assert_approx_eq!(0.5f128.atanh(), 0.54930614433405484569762261846126285f128, TOL_IMPR);
-    assert_approx_eq!((-0.5f128).atanh(), -0.54930614433405484569762261846126285f128, TOL_IMPR);
-}
-
-#[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f128_math)]
-fn test_gamma() {
-    // precision can differ among platforms
-    assert_approx_eq!(1.0f128.gamma(), 1.0f128, TOL_IMPR);
-    assert_approx_eq!(2.0f128.gamma(), 1.0f128, TOL_IMPR);
-    assert_approx_eq!(3.0f128.gamma(), 2.0f128, TOL_IMPR);
-    assert_approx_eq!(4.0f128.gamma(), 6.0f128, TOL_IMPR);
-    assert_approx_eq!(5.0f128.gamma(), 24.0f128, TOL_IMPR);
-    assert_approx_eq!(0.5f128.gamma(), consts::PI.sqrt(), TOL_IMPR);
-    assert_approx_eq!((-0.5f128).gamma(), -2.0 * consts::PI.sqrt(), TOL_IMPR);
-    assert_eq!(0.0f128.gamma(), f128::INFINITY);
-    assert_eq!((-0.0f128).gamma(), f128::NEG_INFINITY);
-    assert!((-1.0f128).gamma().is_nan());
-    assert!((-2.0f128).gamma().is_nan());
-    assert!(f128::NAN.gamma().is_nan());
-    assert!(f128::NEG_INFINITY.gamma().is_nan());
-    assert_eq!(f128::INFINITY.gamma(), f128::INFINITY);
-    assert_eq!(1760.9f128.gamma(), f128::INFINITY);
-}
-
-#[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f128_math)]
-fn test_ln_gamma() {
-    assert_approx_eq!(1.0f128.ln_gamma().0, 0.0f128, TOL_IMPR);
-    assert_eq!(1.0f128.ln_gamma().1, 1);
-    assert_approx_eq!(2.0f128.ln_gamma().0, 0.0f128, TOL_IMPR);
-    assert_eq!(2.0f128.ln_gamma().1, 1);
-    assert_approx_eq!(3.0f128.ln_gamma().0, 2.0f128.ln(), TOL_IMPR);
-    assert_eq!(3.0f128.ln_gamma().1, 1);
-    assert_approx_eq!((-0.5f128).ln_gamma().0, (2.0 * consts::PI.sqrt()).ln(), TOL_IMPR);
-    assert_eq!((-0.5f128).ln_gamma().1, -1);
-}
-
-#[test]
-fn test_real_consts() {
-    let pi: f128 = consts::PI;
-    let frac_pi_2: f128 = consts::FRAC_PI_2;
-    let frac_pi_3: f128 = consts::FRAC_PI_3;
-    let frac_pi_4: f128 = consts::FRAC_PI_4;
-    let frac_pi_6: f128 = consts::FRAC_PI_6;
-    let frac_pi_8: f128 = consts::FRAC_PI_8;
-    let frac_1_pi: f128 = consts::FRAC_1_PI;
-    let frac_2_pi: f128 = consts::FRAC_2_PI;
-
-    assert_approx_eq!(frac_pi_2, pi / 2f128, TOL_PRECISE);
-    assert_approx_eq!(frac_pi_3, pi / 3f128, TOL_PRECISE);
-    assert_approx_eq!(frac_pi_4, pi / 4f128, TOL_PRECISE);
-    assert_approx_eq!(frac_pi_6, pi / 6f128, TOL_PRECISE);
-    assert_approx_eq!(frac_pi_8, pi / 8f128, TOL_PRECISE);
-    assert_approx_eq!(frac_1_pi, 1f128 / pi, TOL_PRECISE);
-    assert_approx_eq!(frac_2_pi, 2f128 / pi, TOL_PRECISE);
-
-    #[cfg(not(miri))]
-    #[cfg(target_has_reliable_f128_math)]
-    {
-        let frac_2_sqrtpi: f128 = consts::FRAC_2_SQRT_PI;
-        let sqrt2: f128 = consts::SQRT_2;
-        let frac_1_sqrt2: f128 = consts::FRAC_1_SQRT_2;
-        let e: f128 = consts::E;
-        let log2_e: f128 = consts::LOG2_E;
-        let log10_e: f128 = consts::LOG10_E;
-        let ln_2: f128 = consts::LN_2;
-        let ln_10: f128 = consts::LN_10;
-
-        assert_approx_eq!(frac_2_sqrtpi, 2f128 / pi.sqrt(), TOL_PRECISE);
-        assert_approx_eq!(sqrt2, 2f128.sqrt(), TOL_PRECISE);
-        assert_approx_eq!(frac_1_sqrt2, 1f128 / 2f128.sqrt(), TOL_PRECISE);
-        assert_approx_eq!(log2_e, e.log2(), TOL_PRECISE);
-        assert_approx_eq!(log10_e, e.log10(), TOL_PRECISE);
-        assert_approx_eq!(ln_2, 2f128.ln(), TOL_PRECISE);
-        assert_approx_eq!(ln_10, 10f128.ln(), TOL_PRECISE);
-    }
-}
-
-#[test]
 fn test_float_bits_conv() {
     assert_eq!((1f128).to_bits(), 0x3fff0000000000000000000000000000);
     assert_eq!((12.5f128).to_bits(), 0x40029000000000000000000000000000);
diff --git a/library/coretests/tests/floats/f16.rs b/library/coretests/tests/floats/f16.rs
index 70bbcd07160..db98181226c 100644
--- a/library/coretests/tests/floats/f16.rs
+++ b/library/coretests/tests/floats/f16.rs
@@ -54,7 +54,7 @@ macro_rules! assert_f16_biteq {
 
 #[test]
 fn test_num_f16() {
-    crate::test_num(10f16, 2f16);
+    super::test_num(10f16, 2f16);
 }
 
 // FIXME(f16_f128,miri): many of these have to be disabled since miri does not yet support
@@ -495,24 +495,6 @@ fn test_powi() {
 #[test]
 #[cfg(not(miri))]
 #[cfg(target_has_reliable_f16_math)]
-fn test_powf() {
-    let nan: f16 = f16::NAN;
-    let inf: f16 = f16::INFINITY;
-    let neg_inf: f16 = f16::NEG_INFINITY;
-    assert_eq!(1.0f16.powf(1.0), 1.0);
-    assert_approx_eq!(3.4f16.powf(4.5), 246.408183, TOL_P2);
-    assert_approx_eq!(2.7f16.powf(-3.2), 0.041652, TOL_N2);
-    assert_approx_eq!((-3.1f16).powf(2.0), 9.61, TOL_P2);
-    assert_approx_eq!(5.9f16.powf(-2.0), 0.028727, TOL_N2);
-    assert_eq!(8.3f16.powf(0.0), 1.0);
-    assert!(nan.powf(2.0).is_nan());
-    assert_eq!(inf.powf(2.0), inf);
-    assert_eq!(neg_inf.powf(3.0), neg_inf);
-}
-
-#[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f16_math)]
 fn test_sqrt_domain() {
     assert!(f16::NAN.sqrt().is_nan());
     assert!(f16::NEG_INFINITY.sqrt().is_nan());
@@ -524,111 +506,6 @@ fn test_sqrt_domain() {
 }
 
 #[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f16_math)]
-fn test_exp() {
-    assert_eq!(1.0, 0.0f16.exp());
-    assert_approx_eq!(2.718282, 1.0f16.exp(), TOL_0);
-    assert_approx_eq!(148.413159, 5.0f16.exp(), TOL_0);
-
-    let inf: f16 = f16::INFINITY;
-    let neg_inf: f16 = f16::NEG_INFINITY;
-    let nan: f16 = f16::NAN;
-    assert_eq!(inf, inf.exp());
-    assert_eq!(0.0, neg_inf.exp());
-    assert!(nan.exp().is_nan());
-}
-
-#[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f16_math)]
-fn test_exp2() {
-    assert_eq!(32.0, 5.0f16.exp2());
-    assert_eq!(1.0, 0.0f16.exp2());
-
-    let inf: f16 = f16::INFINITY;
-    let neg_inf: f16 = f16::NEG_INFINITY;
-    let nan: f16 = f16::NAN;
-    assert_eq!(inf, inf.exp2());
-    assert_eq!(0.0, neg_inf.exp2());
-    assert!(nan.exp2().is_nan());
-}
-
-#[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f16_math)]
-fn test_ln() {
-    let nan: f16 = f16::NAN;
-    let inf: f16 = f16::INFINITY;
-    let neg_inf: f16 = f16::NEG_INFINITY;
-    assert_approx_eq!(1.0f16.exp().ln(), 1.0, TOL_0);
-    assert!(nan.ln().is_nan());
-    assert_eq!(inf.ln(), inf);
-    assert!(neg_inf.ln().is_nan());
-    assert!((-2.3f16).ln().is_nan());
-    assert_eq!((-0.0f16).ln(), neg_inf);
-    assert_eq!(0.0f16.ln(), neg_inf);
-    assert_approx_eq!(4.0f16.ln(), 1.386294, TOL_0);
-}
-
-#[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f16_math)]
-fn test_log() {
-    let nan: f16 = f16::NAN;
-    let inf: f16 = f16::INFINITY;
-    let neg_inf: f16 = f16::NEG_INFINITY;
-    assert_eq!(10.0f16.log(10.0), 1.0);
-    assert_approx_eq!(2.3f16.log(3.5), 0.664858, TOL_0);
-    assert_eq!(1.0f16.exp().log(1.0f16.exp()), 1.0);
-    assert!(1.0f16.log(1.0).is_nan());
-    assert!(1.0f16.log(-13.9).is_nan());
-    assert!(nan.log(2.3).is_nan());
-    assert_eq!(inf.log(10.0), inf);
-    assert!(neg_inf.log(8.8).is_nan());
-    assert!((-2.3f16).log(0.1).is_nan());
-    assert_eq!((-0.0f16).log(2.0), neg_inf);
-    assert_eq!(0.0f16.log(7.0), neg_inf);
-}
-
-#[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f16_math)]
-fn test_log2() {
-    let nan: f16 = f16::NAN;
-    let inf: f16 = f16::INFINITY;
-    let neg_inf: f16 = f16::NEG_INFINITY;
-    assert_approx_eq!(10.0f16.log2(), 3.321928, TOL_0);
-    assert_approx_eq!(2.3f16.log2(), 1.201634, TOL_0);
-    assert_approx_eq!(1.0f16.exp().log2(), 1.442695, TOL_0);
-    assert!(nan.log2().is_nan());
-    assert_eq!(inf.log2(), inf);
-    assert!(neg_inf.log2().is_nan());
-    assert!((-2.3f16).log2().is_nan());
-    assert_eq!((-0.0f16).log2(), neg_inf);
-    assert_eq!(0.0f16.log2(), neg_inf);
-}
-
-#[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f16_math)]
-fn test_log10() {
-    let nan: f16 = f16::NAN;
-    let inf: f16 = f16::INFINITY;
-    let neg_inf: f16 = f16::NEG_INFINITY;
-    assert_eq!(10.0f16.log10(), 1.0);
-    assert_approx_eq!(2.3f16.log10(), 0.361728, TOL_0);
-    assert_approx_eq!(1.0f16.exp().log10(), 0.434294, TOL_0);
-    assert_eq!(1.0f16.log10(), 0.0);
-    assert!(nan.log10().is_nan());
-    assert_eq!(inf.log10(), inf);
-    assert!(neg_inf.log10().is_nan());
-    assert!((-2.3f16).log10().is_nan());
-    assert_eq!((-0.0f16).log10(), neg_inf);
-    assert_eq!(0.0f16.log10(), neg_inf);
-}
-
-#[test]
 fn test_to_degrees() {
     let pi: f16 = consts::PI;
     let nan: f16 = f16::NAN;
@@ -659,152 +536,6 @@ fn test_to_radians() {
 }
 
 #[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f16_math)]
-fn test_asinh() {
-    assert_eq!(0.0f16.asinh(), 0.0f16);
-    assert_eq!((-0.0f16).asinh(), -0.0f16);
-
-    let inf: f16 = f16::INFINITY;
-    let neg_inf: f16 = f16::NEG_INFINITY;
-    let nan: f16 = f16::NAN;
-    assert_eq!(inf.asinh(), inf);
-    assert_eq!(neg_inf.asinh(), neg_inf);
-    assert!(nan.asinh().is_nan());
-    assert!((-0.0f16).asinh().is_sign_negative());
-    // issue 63271
-    assert_approx_eq!(2.0f16.asinh(), 1.443635475178810342493276740273105f16, TOL_0);
-    assert_approx_eq!((-2.0f16).asinh(), -1.443635475178810342493276740273105f16, TOL_0);
-    // regression test for the catastrophic cancellation fixed in 72486
-    assert_approx_eq!((-200.0f16).asinh(), -5.991470797049389, TOL_0);
-
-    // test for low accuracy from issue 104548
-    assert_approx_eq!(10.0f16, 10.0f16.sinh().asinh(), TOL_0);
-    // mul needed for approximate comparison to be meaningful
-    assert_approx_eq!(1.0f16, 1e-3f16.sinh().asinh() * 1e3f16, TOL_0);
-}
-
-#[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f16_math)]
-fn test_acosh() {
-    assert_eq!(1.0f16.acosh(), 0.0f16);
-    assert!(0.999f16.acosh().is_nan());
-
-    let inf: f16 = f16::INFINITY;
-    let neg_inf: f16 = f16::NEG_INFINITY;
-    let nan: f16 = f16::NAN;
-    assert_eq!(inf.acosh(), inf);
-    assert!(neg_inf.acosh().is_nan());
-    assert!(nan.acosh().is_nan());
-    assert_approx_eq!(2.0f16.acosh(), 1.31695789692481670862504634730796844f16, TOL_0);
-    assert_approx_eq!(3.0f16.acosh(), 1.76274717403908605046521864995958461f16, TOL_0);
-
-    // test for low accuracy from issue 104548
-    assert_approx_eq!(10.0f16, 10.0f16.cosh().acosh(), TOL_P2);
-}
-
-#[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f16_math)]
-fn test_atanh() {
-    assert_eq!(0.0f16.atanh(), 0.0f16);
-    assert_eq!((-0.0f16).atanh(), -0.0f16);
-
-    let inf: f16 = f16::INFINITY;
-    let neg_inf: f16 = f16::NEG_INFINITY;
-    let nan: f16 = f16::NAN;
-    assert_eq!(1.0f16.atanh(), inf);
-    assert_eq!((-1.0f16).atanh(), neg_inf);
-    assert!(2f16.atanh().atanh().is_nan());
-    assert!((-2f16).atanh().atanh().is_nan());
-    assert!(inf.atanh().is_nan());
-    assert!(neg_inf.atanh().is_nan());
-    assert!(nan.atanh().is_nan());
-    assert_approx_eq!(0.5f16.atanh(), 0.54930614433405484569762261846126285f16, TOL_0);
-    assert_approx_eq!((-0.5f16).atanh(), -0.54930614433405484569762261846126285f16, TOL_0);
-}
-
-#[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f16_math)]
-fn test_gamma() {
-    // precision can differ among platforms
-    assert_approx_eq!(1.0f16.gamma(), 1.0f16, TOL_0);
-    assert_approx_eq!(2.0f16.gamma(), 1.0f16, TOL_0);
-    assert_approx_eq!(3.0f16.gamma(), 2.0f16, TOL_0);
-    assert_approx_eq!(4.0f16.gamma(), 6.0f16, TOL_0);
-    assert_approx_eq!(5.0f16.gamma(), 24.0f16, TOL_0);
-    assert_approx_eq!(0.5f16.gamma(), consts::PI.sqrt(), TOL_0);
-    assert_approx_eq!((-0.5f16).gamma(), -2.0 * consts::PI.sqrt(), TOL_0);
-    assert_eq!(0.0f16.gamma(), f16::INFINITY);
-    assert_eq!((-0.0f16).gamma(), f16::NEG_INFINITY);
-    assert!((-1.0f16).gamma().is_nan());
-    assert!((-2.0f16).gamma().is_nan());
-    assert!(f16::NAN.gamma().is_nan());
-    assert!(f16::NEG_INFINITY.gamma().is_nan());
-    assert_eq!(f16::INFINITY.gamma(), f16::INFINITY);
-    assert_eq!(171.71f16.gamma(), f16::INFINITY);
-}
-
-#[test]
-#[cfg(not(miri))]
-#[cfg(target_has_reliable_f16_math)]
-fn test_ln_gamma() {
-    assert_approx_eq!(1.0f16.ln_gamma().0, 0.0f16, TOL_0);
-    assert_eq!(1.0f16.ln_gamma().1, 1);
-    assert_approx_eq!(2.0f16.ln_gamma().0, 0.0f16, TOL_0);
-    assert_eq!(2.0f16.ln_gamma().1, 1);
-    assert_approx_eq!(3.0f16.ln_gamma().0, 2.0f16.ln(), TOL_0);
-    assert_eq!(3.0f16.ln_gamma().1, 1);
-    assert_approx_eq!((-0.5f16).ln_gamma().0, (2.0 * consts::PI.sqrt()).ln(), TOL_0);
-    assert_eq!((-0.5f16).ln_gamma().1, -1);
-}
-
-#[test]
-fn test_real_consts() {
-    // FIXME(f16_f128): add math tests when available
-
-    let pi: f16 = consts::PI;
-    let frac_pi_2: f16 = consts::FRAC_PI_2;
-    let frac_pi_3: f16 = consts::FRAC_PI_3;
-    let frac_pi_4: f16 = consts::FRAC_PI_4;
-    let frac_pi_6: f16 = consts::FRAC_PI_6;
-    let frac_pi_8: f16 = consts::FRAC_PI_8;
-    let frac_1_pi: f16 = consts::FRAC_1_PI;
-    let frac_2_pi: f16 = consts::FRAC_2_PI;
-
-    assert_approx_eq!(frac_pi_2, pi / 2f16, TOL_0);
-    assert_approx_eq!(frac_pi_3, pi / 3f16, TOL_0);
-    assert_approx_eq!(frac_pi_4, pi / 4f16, TOL_0);
-    assert_approx_eq!(frac_pi_6, pi / 6f16, TOL_0);
-    assert_approx_eq!(frac_pi_8, pi / 8f16, TOL_0);
-    assert_approx_eq!(frac_1_pi, 1f16 / pi, TOL_0);
-    assert_approx_eq!(frac_2_pi, 2f16 / pi, TOL_0);
-
-    #[cfg(not(miri))]
-    #[cfg(target_has_reliable_f16_math)]
-    {
-        let frac_2_sqrtpi: f16 = consts::FRAC_2_SQRT_PI;
-        let sqrt2: f16 = consts::SQRT_2;
-        let frac_1_sqrt2: f16 = consts::FRAC_1_SQRT_2;
-        let e: f16 = consts::E;
-        let log2_e: f16 = consts::LOG2_E;
-        let log10_e: f16 = consts::LOG10_E;
-        let ln_2: f16 = consts::LN_2;
-        let ln_10: f16 = consts::LN_10;
-
-        assert_approx_eq!(frac_2_sqrtpi, 2f16 / pi.sqrt(), TOL_0);
-        assert_approx_eq!(sqrt2, 2f16.sqrt(), TOL_0);
-        assert_approx_eq!(frac_1_sqrt2, 1f16 / 2f16.sqrt(), TOL_0);
-        assert_approx_eq!(log2_e, e.log2(), TOL_0);
-        assert_approx_eq!(log10_e, e.log10(), TOL_0);
-        assert_approx_eq!(ln_2, 2f16.ln(), TOL_0);
-        assert_approx_eq!(ln_10, 10f16.ln(), TOL_0);
-    }
-}
-
-#[test]
 fn test_float_bits_conv() {
     assert_eq!((1f16).to_bits(), 0x3c00);
     assert_eq!((12.5f16).to_bits(), 0x4a40);
diff --git a/library/coretests/tests/floats/f32.rs b/library/coretests/tests/floats/f32.rs
index 9af23afc5bb..1c018a5e7b5 100644
--- a/library/coretests/tests/floats/f32.rs
+++ b/library/coretests/tests/floats/f32.rs
@@ -1,5 +1,6 @@
-use std::f32::consts;
-use std::num::FpCategory as Fp;
+use core::f32;
+use core::f32::consts;
+use core::num::FpCategory as Fp;
 
 /// Smallest number
 const TINY_BITS: u32 = 0x1;
@@ -35,7 +36,7 @@ macro_rules! assert_f32_biteq {
 
 #[test]
 fn test_num_f32() {
-    crate::test_num(10f32, 2f32);
+    super::test_num(10f32, 2f32);
 }
 
 #[test]
@@ -214,88 +215,88 @@ fn test_classify() {
 
 #[test]
 fn test_floor() {
-    assert_approx_eq!(1.0f32.floor(), 1.0f32);
-    assert_approx_eq!(1.3f32.floor(), 1.0f32);
-    assert_approx_eq!(1.5f32.floor(), 1.0f32);
-    assert_approx_eq!(1.7f32.floor(), 1.0f32);
-    assert_approx_eq!(0.0f32.floor(), 0.0f32);
-    assert_approx_eq!((-0.0f32).floor(), -0.0f32);
-    assert_approx_eq!((-1.0f32).floor(), -1.0f32);
-    assert_approx_eq!((-1.3f32).floor(), -2.0f32);
-    assert_approx_eq!((-1.5f32).floor(), -2.0f32);
-    assert_approx_eq!((-1.7f32).floor(), -2.0f32);
+    assert_approx_eq!(f32::floor(1.0f32), 1.0f32);
+    assert_approx_eq!(f32::floor(1.3f32), 1.0f32);
+    assert_approx_eq!(f32::floor(1.5f32), 1.0f32);
+    assert_approx_eq!(f32::floor(1.7f32), 1.0f32);
+    assert_approx_eq!(f32::floor(0.0f32), 0.0f32);
+    assert_approx_eq!(f32::floor(-0.0f32), -0.0f32);
+    assert_approx_eq!(f32::floor(-1.0f32), -1.0f32);
+    assert_approx_eq!(f32::floor(-1.3f32), -2.0f32);
+    assert_approx_eq!(f32::floor(-1.5f32), -2.0f32);
+    assert_approx_eq!(f32::floor(-1.7f32), -2.0f32);
 }
 
 #[test]
 fn test_ceil() {
-    assert_approx_eq!(1.0f32.ceil(), 1.0f32);
-    assert_approx_eq!(1.3f32.ceil(), 2.0f32);
-    assert_approx_eq!(1.5f32.ceil(), 2.0f32);
-    assert_approx_eq!(1.7f32.ceil(), 2.0f32);
-    assert_approx_eq!(0.0f32.ceil(), 0.0f32);
-    assert_approx_eq!((-0.0f32).ceil(), -0.0f32);
-    assert_approx_eq!((-1.0f32).ceil(), -1.0f32);
-    assert_approx_eq!((-1.3f32).ceil(), -1.0f32);
-    assert_approx_eq!((-1.5f32).ceil(), -1.0f32);
-    assert_approx_eq!((-1.7f32).ceil(), -1.0f32);
+    assert_approx_eq!(f32::ceil(1.0f32), 1.0f32);
+    assert_approx_eq!(f32::ceil(1.3f32), 2.0f32);
+    assert_approx_eq!(f32::ceil(1.5f32), 2.0f32);
+    assert_approx_eq!(f32::ceil(1.7f32), 2.0f32);
+    assert_approx_eq!(f32::ceil(0.0f32), 0.0f32);
+    assert_approx_eq!(f32::ceil(-0.0f32), -0.0f32);
+    assert_approx_eq!(f32::ceil(-1.0f32), -1.0f32);
+    assert_approx_eq!(f32::ceil(-1.3f32), -1.0f32);
+    assert_approx_eq!(f32::ceil(-1.5f32), -1.0f32);
+    assert_approx_eq!(f32::ceil(-1.7f32), -1.0f32);
 }
 
 #[test]
 fn test_round() {
-    assert_approx_eq!(2.5f32.round(), 3.0f32);
-    assert_approx_eq!(1.0f32.round(), 1.0f32);
-    assert_approx_eq!(1.3f32.round(), 1.0f32);
-    assert_approx_eq!(1.5f32.round(), 2.0f32);
-    assert_approx_eq!(1.7f32.round(), 2.0f32);
-    assert_approx_eq!(0.0f32.round(), 0.0f32);
-    assert_approx_eq!((-0.0f32).round(), -0.0f32);
-    assert_approx_eq!((-1.0f32).round(), -1.0f32);
-    assert_approx_eq!((-1.3f32).round(), -1.0f32);
-    assert_approx_eq!((-1.5f32).round(), -2.0f32);
-    assert_approx_eq!((-1.7f32).round(), -2.0f32);
+    assert_approx_eq!(f32::round(2.5f32), 3.0f32);
+    assert_approx_eq!(f32::round(1.0f32), 1.0f32);
+    assert_approx_eq!(f32::round(1.3f32), 1.0f32);
+    assert_approx_eq!(f32::round(1.5f32), 2.0f32);
+    assert_approx_eq!(f32::round(1.7f32), 2.0f32);
+    assert_approx_eq!(f32::round(0.0f32), 0.0f32);
+    assert_approx_eq!(f32::round(-0.0f32), -0.0f32);
+    assert_approx_eq!(f32::round(-1.0f32), -1.0f32);
+    assert_approx_eq!(f32::round(-1.3f32), -1.0f32);
+    assert_approx_eq!(f32::round(-1.5f32), -2.0f32);
+    assert_approx_eq!(f32::round(-1.7f32), -2.0f32);
 }
 
 #[test]
 fn test_round_ties_even() {
-    assert_approx_eq!(2.5f32.round_ties_even(), 2.0f32);
-    assert_approx_eq!(1.0f32.round_ties_even(), 1.0f32);
-    assert_approx_eq!(1.3f32.round_ties_even(), 1.0f32);
-    assert_approx_eq!(1.5f32.round_ties_even(), 2.0f32);
-    assert_approx_eq!(1.7f32.round_ties_even(), 2.0f32);
-    assert_approx_eq!(0.0f32.round_ties_even(), 0.0f32);
-    assert_approx_eq!((-0.0f32).round_ties_even(), -0.0f32);
-    assert_approx_eq!((-1.0f32).round_ties_even(), -1.0f32);
-    assert_approx_eq!((-1.3f32).round_ties_even(), -1.0f32);
-    assert_approx_eq!((-1.5f32).round_ties_even(), -2.0f32);
-    assert_approx_eq!((-1.7f32).round_ties_even(), -2.0f32);
+    assert_approx_eq!(f32::round_ties_even(2.5f32), 2.0f32);
+    assert_approx_eq!(f32::round_ties_even(1.0f32), 1.0f32);
+    assert_approx_eq!(f32::round_ties_even(1.3f32), 1.0f32);
+    assert_approx_eq!(f32::round_ties_even(1.5f32), 2.0f32);
+    assert_approx_eq!(f32::round_ties_even(1.7f32), 2.0f32);
+    assert_approx_eq!(f32::round_ties_even(0.0f32), 0.0f32);
+    assert_approx_eq!(f32::round_ties_even(-0.0f32), -0.0f32);
+    assert_approx_eq!(f32::round_ties_even(-1.0f32), -1.0f32);
+    assert_approx_eq!(f32::round_ties_even(-1.3f32), -1.0f32);
+    assert_approx_eq!(f32::round_ties_even(-1.5f32), -2.0f32);
+    assert_approx_eq!(f32::round_ties_even(-1.7f32), -2.0f32);
 }
 
 #[test]
 fn test_trunc() {
-    assert_approx_eq!(1.0f32.trunc(), 1.0f32);
-    assert_approx_eq!(1.3f32.trunc(), 1.0f32);
-    assert_approx_eq!(1.5f32.trunc(), 1.0f32);
-    assert_approx_eq!(1.7f32.trunc(), 1.0f32);
-    assert_approx_eq!(0.0f32.trunc(), 0.0f32);
-    assert_approx_eq!((-0.0f32).trunc(), -0.0f32);
-    assert_approx_eq!((-1.0f32).trunc(), -1.0f32);
-    assert_approx_eq!((-1.3f32).trunc(), -1.0f32);
-    assert_approx_eq!((-1.5f32).trunc(), -1.0f32);
-    assert_approx_eq!((-1.7f32).trunc(), -1.0f32);
+    assert_approx_eq!(f32::trunc(1.0f32), 1.0f32);
+    assert_approx_eq!(f32::trunc(1.3f32), 1.0f32);
+    assert_approx_eq!(f32::trunc(1.5f32), 1.0f32);
+    assert_approx_eq!(f32::trunc(1.7f32), 1.0f32);
+    assert_approx_eq!(f32::trunc(0.0f32), 0.0f32);
+    assert_approx_eq!(f32::trunc(-0.0f32), -0.0f32);
+    assert_approx_eq!(f32::trunc(-1.0f32), -1.0f32);
+    assert_approx_eq!(f32::trunc(-1.3f32), -1.0f32);
+    assert_approx_eq!(f32::trunc(-1.5f32), -1.0f32);
+    assert_approx_eq!(f32::trunc(-1.7f32), -1.0f32);
 }
 
 #[test]
 fn test_fract() {
-    assert_approx_eq!(1.0f32.fract(), 0.0f32);
-    assert_approx_eq!(1.3f32.fract(), 0.3f32);
-    assert_approx_eq!(1.5f32.fract(), 0.5f32);
-    assert_approx_eq!(1.7f32.fract(), 0.7f32);
-    assert_approx_eq!(0.0f32.fract(), 0.0f32);
-    assert_approx_eq!((-0.0f32).fract(), -0.0f32);
-    assert_approx_eq!((-1.0f32).fract(), -0.0f32);
-    assert_approx_eq!((-1.3f32).fract(), -0.3f32);
-    assert_approx_eq!((-1.5f32).fract(), -0.5f32);
-    assert_approx_eq!((-1.7f32).fract(), -0.7f32);
+    assert_approx_eq!(f32::fract(1.0f32), 0.0f32);
+    assert_approx_eq!(f32::fract(1.3f32), 0.3f32);
+    assert_approx_eq!(f32::fract(1.5f32), 0.5f32);
+    assert_approx_eq!(f32::fract(1.7f32), 0.7f32);
+    assert_approx_eq!(f32::fract(0.0f32), 0.0f32);
+    assert_approx_eq!(f32::fract(-0.0f32), -0.0f32);
+    assert_approx_eq!(f32::fract(-1.0f32), -0.0f32);
+    assert_approx_eq!(f32::fract(-1.3f32), -0.3f32);
+    assert_approx_eq!(f32::fract(-1.5f32), -0.5f32);
+    assert_approx_eq!(f32::fract(-1.7f32), -0.7f32);
 }
 
 #[test]
@@ -414,15 +415,15 @@ fn test_mul_add() {
     let nan: f32 = f32::NAN;
     let inf: f32 = f32::INFINITY;
     let neg_inf: f32 = f32::NEG_INFINITY;
-    assert_approx_eq!(12.3f32.mul_add(4.5, 6.7), 62.05);
-    assert_approx_eq!((-12.3f32).mul_add(-4.5, -6.7), 48.65);
-    assert_approx_eq!(0.0f32.mul_add(8.9, 1.2), 1.2);
-    assert_approx_eq!(3.4f32.mul_add(-0.0, 5.6), 5.6);
-    assert!(nan.mul_add(7.8, 9.0).is_nan());
-    assert_eq!(inf.mul_add(7.8, 9.0), inf);
-    assert_eq!(neg_inf.mul_add(7.8, 9.0), neg_inf);
-    assert_eq!(8.9f32.mul_add(inf, 3.2), inf);
-    assert_eq!((-3.2f32).mul_add(2.4, neg_inf), neg_inf);
+    assert_approx_eq!(f32::mul_add(12.3f32, 4.5, 6.7), 62.05);
+    assert_approx_eq!(f32::mul_add(-12.3f32, -4.5, -6.7), 48.65);
+    assert_approx_eq!(f32::mul_add(0.0f32, 8.9, 1.2), 1.2);
+    assert_approx_eq!(f32::mul_add(3.4f32, -0.0, 5.6), 5.6);
+    assert!(f32::mul_add(nan, 7.8, 9.0).is_nan());
+    assert_eq!(f32::mul_add(inf, 7.8, 9.0), inf);
+    assert_eq!(f32::mul_add(neg_inf, 7.8, 9.0), neg_inf);
+    assert_eq!(f32::mul_add(8.9f32, inf, 3.2), inf);
+    assert_eq!(f32::mul_add(-3.2f32, 2.4, neg_inf), neg_inf);
 }
 
 #[test]
@@ -454,22 +455,6 @@ fn test_powi() {
 }
 
 #[test]
-fn test_powf() {
-    let nan: f32 = f32::NAN;
-    let inf: f32 = f32::INFINITY;
-    let neg_inf: f32 = f32::NEG_INFINITY;
-    assert_eq!(1.0f32.powf(1.0), 1.0);
-    assert_approx_eq!(3.4f32.powf(4.5), 246.408218);
-    assert_approx_eq!(2.7f32.powf(-3.2), 0.041652);
-    assert_approx_eq!((-3.1f32).powf(2.0), 9.61);
-    assert_approx_eq!(5.9f32.powf(-2.0), 0.028727);
-    assert_eq!(8.3f32.powf(0.0), 1.0);
-    assert!(nan.powf(2.0).is_nan());
-    assert_eq!(inf.powf(2.0), inf);
-    assert_eq!(neg_inf.powf(3.0), neg_inf);
-}
-
-#[test]
 fn test_sqrt_domain() {
     assert!(f32::NAN.sqrt().is_nan());
     assert!(f32::NEG_INFINITY.sqrt().is_nan());
@@ -481,99 +466,6 @@ fn test_sqrt_domain() {
 }
 
 #[test]
-fn test_exp() {
-    assert_eq!(1.0, 0.0f32.exp());
-    assert_approx_eq!(2.718282, 1.0f32.exp());
-    assert_approx_eq!(148.413162, 5.0f32.exp());
-
-    let inf: f32 = f32::INFINITY;
-    let neg_inf: f32 = f32::NEG_INFINITY;
-    let nan: f32 = f32::NAN;
-    assert_eq!(inf, inf.exp());
-    assert_eq!(0.0, neg_inf.exp());
-    assert!(nan.exp().is_nan());
-}
-
-#[test]
-fn test_exp2() {
-    assert_eq!(32.0, 5.0f32.exp2());
-    assert_eq!(1.0, 0.0f32.exp2());
-
-    let inf: f32 = f32::INFINITY;
-    let neg_inf: f32 = f32::NEG_INFINITY;
-    let nan: f32 = f32::NAN;
-    assert_eq!(inf, inf.exp2());
-    assert_eq!(0.0, neg_inf.exp2());
-    assert!(nan.exp2().is_nan());
-}
-
-#[test]
-fn test_ln() {
-    let nan: f32 = f32::NAN;
-    let inf: f32 = f32::INFINITY;
-    let neg_inf: f32 = f32::NEG_INFINITY;
-    assert_approx_eq!(1.0f32.exp().ln(), 1.0);
-    assert!(nan.ln().is_nan());
-    assert_eq!(inf.ln(), inf);
-    assert!(neg_inf.ln().is_nan());
-    assert!((-2.3f32).ln().is_nan());
-    assert_eq!((-0.0f32).ln(), neg_inf);
-    assert_eq!(0.0f32.ln(), neg_inf);
-    assert_approx_eq!(4.0f32.ln(), 1.386294);
-}
-
-#[test]
-fn test_log() {
-    let nan: f32 = f32::NAN;
-    let inf: f32 = f32::INFINITY;
-    let neg_inf: f32 = f32::NEG_INFINITY;
-    assert_eq!(10.0f32.log(10.0), 1.0);
-    assert_approx_eq!(2.3f32.log(3.5), 0.664858);
-    assert_eq!(1.0f32.exp().log(1.0f32.exp()), 1.0);
-    assert!(1.0f32.log(1.0).is_nan());
-    assert!(1.0f32.log(-13.9).is_nan());
-    assert!(nan.log(2.3).is_nan());
-    assert_eq!(inf.log(10.0), inf);
-    assert!(neg_inf.log(8.8).is_nan());
-    assert!((-2.3f32).log(0.1).is_nan());
-    assert_eq!((-0.0f32).log(2.0), neg_inf);
-    assert_eq!(0.0f32.log(7.0), neg_inf);
-}
-
-#[test]
-fn test_log2() {
-    let nan: f32 = f32::NAN;
-    let inf: f32 = f32::INFINITY;
-    let neg_inf: f32 = f32::NEG_INFINITY;
-    assert_approx_eq!(10.0f32.log2(), 3.321928);
-    assert_approx_eq!(2.3f32.log2(), 1.201634);
-    assert_approx_eq!(1.0f32.exp().log2(), 1.442695);
-    assert!(nan.log2().is_nan());
-    assert_eq!(inf.log2(), inf);
-    assert!(neg_inf.log2().is_nan());
-    assert!((-2.3f32).log2().is_nan());
-    assert_eq!((-0.0f32).log2(), neg_inf);
-    assert_eq!(0.0f32.log2(), neg_inf);
-}
-
-#[test]
-fn test_log10() {
-    let nan: f32 = f32::NAN;
-    let inf: f32 = f32::INFINITY;
-    let neg_inf: f32 = f32::NEG_INFINITY;
-    assert_eq!(10.0f32.log10(), 1.0);
-    assert_approx_eq!(2.3f32.log10(), 0.361728);
-    assert_approx_eq!(1.0f32.exp().log10(), 0.434294);
-    assert_eq!(1.0f32.log10(), 0.0);
-    assert!(nan.log10().is_nan());
-    assert_eq!(inf.log10(), inf);
-    assert!(neg_inf.log10().is_nan());
-    assert!((-2.3f32).log10().is_nan());
-    assert_eq!((-0.0f32).log10(), neg_inf);
-    assert_eq!(0.0f32.log10(), neg_inf);
-}
-
-#[test]
 fn test_to_degrees() {
     let pi: f32 = consts::PI;
     let nan: f32 = f32::NAN;
@@ -604,138 +496,6 @@ fn test_to_radians() {
 }
 
 #[test]
-fn test_asinh() {
-    assert_eq!(0.0f32.asinh(), 0.0f32);
-    assert_eq!((-0.0f32).asinh(), -0.0f32);
-
-    let inf: f32 = f32::INFINITY;
-    let neg_inf: f32 = f32::NEG_INFINITY;
-    let nan: f32 = f32::NAN;
-    assert_eq!(inf.asinh(), inf);
-    assert_eq!(neg_inf.asinh(), neg_inf);
-    assert!(nan.asinh().is_nan());
-    assert!((-0.0f32).asinh().is_sign_negative()); // issue 63271
-    assert_approx_eq!(2.0f32.asinh(), 1.443635475178810342493276740273105f32);
-    assert_approx_eq!((-2.0f32).asinh(), -1.443635475178810342493276740273105f32);
-    // regression test for the catastrophic cancellation fixed in 72486
-    assert_approx_eq!((-3000.0f32).asinh(), -8.699514775987968673236893537700647f32);
-
-    // test for low accuracy from issue 104548
-    assert_approx_eq!(60.0f32, 60.0f32.sinh().asinh());
-    // mul needed for approximate comparison to be meaningful
-    assert_approx_eq!(1.0f32, 1e-15f32.sinh().asinh() * 1e15f32);
-}
-
-#[test]
-fn test_acosh() {
-    assert_eq!(1.0f32.acosh(), 0.0f32);
-    assert!(0.999f32.acosh().is_nan());
-
-    let inf: f32 = f32::INFINITY;
-    let neg_inf: f32 = f32::NEG_INFINITY;
-    let nan: f32 = f32::NAN;
-    assert_eq!(inf.acosh(), inf);
-    assert!(neg_inf.acosh().is_nan());
-    assert!(nan.acosh().is_nan());
-    assert_approx_eq!(2.0f32.acosh(), 1.31695789692481670862504634730796844f32);
-    assert_approx_eq!(3.0f32.acosh(), 1.76274717403908605046521864995958461f32);
-
-    // test for low accuracy from issue 104548
-    assert_approx_eq!(60.0f32, 60.0f32.cosh().acosh());
-}
-
-#[test]
-fn test_atanh() {
-    assert_eq!(0.0f32.atanh(), 0.0f32);
-    assert_eq!((-0.0f32).atanh(), -0.0f32);
-
-    let inf32: f32 = f32::INFINITY;
-    let neg_inf32: f32 = f32::NEG_INFINITY;
-    assert_eq!(1.0f32.atanh(), inf32);
-    assert_eq!((-1.0f32).atanh(), neg_inf32);
-
-    assert!(2f64.atanh().atanh().is_nan());
-    assert!((-2f64).atanh().atanh().is_nan());
-
-    let inf64: f32 = f32::INFINITY;
-    let neg_inf64: f32 = f32::NEG_INFINITY;
-    let nan32: f32 = f32::NAN;
-    assert!(inf64.atanh().is_nan());
-    assert!(neg_inf64.atanh().is_nan());
-    assert!(nan32.atanh().is_nan());
-
-    assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32);
-    assert_approx_eq!((-0.5f32).atanh(), -0.54930614433405484569762261846126285f32);
-}
-
-#[test]
-fn test_gamma() {
-    // precision can differ between platforms
-    assert_approx_eq!(1.0f32.gamma(), 1.0f32);
-    assert_approx_eq!(2.0f32.gamma(), 1.0f32);
-    assert_approx_eq!(3.0f32.gamma(), 2.0f32);
-    assert_approx_eq!(4.0f32.gamma(), 6.0f32);
-    assert_approx_eq!(5.0f32.gamma(), 24.0f32);
-    assert_approx_eq!(0.5f32.gamma(), consts::PI.sqrt());
-    assert_approx_eq!((-0.5f32).gamma(), -2.0 * consts::PI.sqrt());
-    assert_eq!(0.0f32.gamma(), f32::INFINITY);
-    assert_eq!((-0.0f32).gamma(), f32::NEG_INFINITY);
-    assert!((-1.0f32).gamma().is_nan());
-    assert!((-2.0f32).gamma().is_nan());
-    assert!(f32::NAN.gamma().is_nan());
-    assert!(f32::NEG_INFINITY.gamma().is_nan());
-    assert_eq!(f32::INFINITY.gamma(), f32::INFINITY);
-    assert_eq!(171.71f32.gamma(), f32::INFINITY);
-}
-
-#[test]
-fn test_ln_gamma() {
-    assert_approx_eq!(1.0f32.ln_gamma().0, 0.0f32);
-    assert_eq!(1.0f32.ln_gamma().1, 1);
-    assert_approx_eq!(2.0f32.ln_gamma().0, 0.0f32);
-    assert_eq!(2.0f32.ln_gamma().1, 1);
-    assert_approx_eq!(3.0f32.ln_gamma().0, 2.0f32.ln());
-    assert_eq!(3.0f32.ln_gamma().1, 1);
-    assert_approx_eq!((-0.5f32).ln_gamma().0, (2.0 * consts::PI.sqrt()).ln());
-    assert_eq!((-0.5f32).ln_gamma().1, -1);
-}
-
-#[test]
-fn test_real_consts() {
-    let pi: f32 = consts::PI;
-    let frac_pi_2: f32 = consts::FRAC_PI_2;
-    let frac_pi_3: f32 = consts::FRAC_PI_3;
-    let frac_pi_4: f32 = consts::FRAC_PI_4;
-    let frac_pi_6: f32 = consts::FRAC_PI_6;
-    let frac_pi_8: f32 = consts::FRAC_PI_8;
-    let frac_1_pi: f32 = consts::FRAC_1_PI;
-    let frac_2_pi: f32 = consts::FRAC_2_PI;
-    let frac_2_sqrtpi: f32 = consts::FRAC_2_SQRT_PI;
-    let sqrt2: f32 = consts::SQRT_2;
-    let frac_1_sqrt2: f32 = consts::FRAC_1_SQRT_2;
-    let e: f32 = consts::E;
-    let log2_e: f32 = consts::LOG2_E;
-    let log10_e: f32 = consts::LOG10_E;
-    let ln_2: f32 = consts::LN_2;
-    let ln_10: f32 = consts::LN_10;
-
-    assert_approx_eq!(frac_pi_2, pi / 2f32);
-    assert_approx_eq!(frac_pi_3, pi / 3f32);
-    assert_approx_eq!(frac_pi_4, pi / 4f32);
-    assert_approx_eq!(frac_pi_6, pi / 6f32);
-    assert_approx_eq!(frac_pi_8, pi / 8f32);
-    assert_approx_eq!(frac_1_pi, 1f32 / pi);
-    assert_approx_eq!(frac_2_pi, 2f32 / pi);
-    assert_approx_eq!(frac_2_sqrtpi, 2f32 / pi.sqrt());
-    assert_approx_eq!(sqrt2, 2f32.sqrt());
-    assert_approx_eq!(frac_1_sqrt2, 1f32 / 2f32.sqrt());
-    assert_approx_eq!(log2_e, e.log2());
-    assert_approx_eq!(log10_e, e.log10());
-    assert_approx_eq!(ln_2, 2f32.ln());
-    assert_approx_eq!(ln_10, 10f32.ln());
-}
-
-#[test]
 fn test_float_bits_conv() {
     assert_eq!((1f32).to_bits(), 0x3f800000);
     assert_eq!((12.5f32).to_bits(), 0x41480000);
diff --git a/library/coretests/tests/floats/f64.rs b/library/coretests/tests/floats/f64.rs
index de9c27eb33d..4a79a31853e 100644
--- a/library/coretests/tests/floats/f64.rs
+++ b/library/coretests/tests/floats/f64.rs
@@ -35,7 +35,7 @@ macro_rules! assert_f64_biteq {
 
 #[test]
 fn test_num_f64() {
-    crate::test_num(10f64, 2f64);
+    super::test_num(10f64, 2f64);
 }
 
 #[test]
@@ -201,88 +201,88 @@ fn test_classify() {
 
 #[test]
 fn test_floor() {
-    assert_approx_eq!(1.0f64.floor(), 1.0f64);
-    assert_approx_eq!(1.3f64.floor(), 1.0f64);
-    assert_approx_eq!(1.5f64.floor(), 1.0f64);
-    assert_approx_eq!(1.7f64.floor(), 1.0f64);
-    assert_approx_eq!(0.0f64.floor(), 0.0f64);
-    assert_approx_eq!((-0.0f64).floor(), -0.0f64);
-    assert_approx_eq!((-1.0f64).floor(), -1.0f64);
-    assert_approx_eq!((-1.3f64).floor(), -2.0f64);
-    assert_approx_eq!((-1.5f64).floor(), -2.0f64);
-    assert_approx_eq!((-1.7f64).floor(), -2.0f64);
+    assert_approx_eq!(f64::floor(1.0f64), 1.0f64);
+    assert_approx_eq!(f64::floor(1.3f64), 1.0f64);
+    assert_approx_eq!(f64::floor(1.5f64), 1.0f64);
+    assert_approx_eq!(f64::floor(1.7f64), 1.0f64);
+    assert_approx_eq!(f64::floor(0.0f64), 0.0f64);
+    assert_approx_eq!(f64::floor(-0.0f64), -0.0f64);
+    assert_approx_eq!(f64::floor(-1.0f64), -1.0f64);
+    assert_approx_eq!(f64::floor(-1.3f64), -2.0f64);
+    assert_approx_eq!(f64::floor(-1.5f64), -2.0f64);
+    assert_approx_eq!(f64::floor(-1.7f64), -2.0f64);
 }
 
 #[test]
 fn test_ceil() {
-    assert_approx_eq!(1.0f64.ceil(), 1.0f64);
-    assert_approx_eq!(1.3f64.ceil(), 2.0f64);
-    assert_approx_eq!(1.5f64.ceil(), 2.0f64);
-    assert_approx_eq!(1.7f64.ceil(), 2.0f64);
-    assert_approx_eq!(0.0f64.ceil(), 0.0f64);
-    assert_approx_eq!((-0.0f64).ceil(), -0.0f64);
-    assert_approx_eq!((-1.0f64).ceil(), -1.0f64);
-    assert_approx_eq!((-1.3f64).ceil(), -1.0f64);
-    assert_approx_eq!((-1.5f64).ceil(), -1.0f64);
-    assert_approx_eq!((-1.7f64).ceil(), -1.0f64);
+    assert_approx_eq!(f64::ceil(1.0f64), 1.0f64);
+    assert_approx_eq!(f64::ceil(1.3f64), 2.0f64);
+    assert_approx_eq!(f64::ceil(1.5f64), 2.0f64);
+    assert_approx_eq!(f64::ceil(1.7f64), 2.0f64);
+    assert_approx_eq!(f64::ceil(0.0f64), 0.0f64);
+    assert_approx_eq!(f64::ceil(-0.0f64), -0.0f64);
+    assert_approx_eq!(f64::ceil(-1.0f64), -1.0f64);
+    assert_approx_eq!(f64::ceil(-1.3f64), -1.0f64);
+    assert_approx_eq!(f64::ceil(-1.5f64), -1.0f64);
+    assert_approx_eq!(f64::ceil(-1.7f64), -1.0f64);
 }
 
 #[test]
 fn test_round() {
-    assert_approx_eq!(2.5f64.round(), 3.0f64);
-    assert_approx_eq!(1.0f64.round(), 1.0f64);
-    assert_approx_eq!(1.3f64.round(), 1.0f64);
-    assert_approx_eq!(1.5f64.round(), 2.0f64);
-    assert_approx_eq!(1.7f64.round(), 2.0f64);
-    assert_approx_eq!(0.0f64.round(), 0.0f64);
-    assert_approx_eq!((-0.0f64).round(), -0.0f64);
-    assert_approx_eq!((-1.0f64).round(), -1.0f64);
-    assert_approx_eq!((-1.3f64).round(), -1.0f64);
-    assert_approx_eq!((-1.5f64).round(), -2.0f64);
-    assert_approx_eq!((-1.7f64).round(), -2.0f64);
+    assert_approx_eq!(f64::round(2.5f64), 3.0f64);
+    assert_approx_eq!(f64::round(1.0f64), 1.0f64);
+    assert_approx_eq!(f64::round(1.3f64), 1.0f64);
+    assert_approx_eq!(f64::round(1.5f64), 2.0f64);
+    assert_approx_eq!(f64::round(1.7f64), 2.0f64);
+    assert_approx_eq!(f64::round(0.0f64), 0.0f64);
+    assert_approx_eq!(f64::round(-0.0f64), -0.0f64);
+    assert_approx_eq!(f64::round(-1.0f64), -1.0f64);
+    assert_approx_eq!(f64::round(-1.3f64), -1.0f64);
+    assert_approx_eq!(f64::round(-1.5f64), -2.0f64);
+    assert_approx_eq!(f64::round(-1.7f64), -2.0f64);
 }
 
 #[test]
 fn test_round_ties_even() {
-    assert_approx_eq!(2.5f64.round_ties_even(), 2.0f64);
-    assert_approx_eq!(1.0f64.round_ties_even(), 1.0f64);
-    assert_approx_eq!(1.3f64.round_ties_even(), 1.0f64);
-    assert_approx_eq!(1.5f64.round_ties_even(), 2.0f64);
-    assert_approx_eq!(1.7f64.round_ties_even(), 2.0f64);
-    assert_approx_eq!(0.0f64.round_ties_even(), 0.0f64);
-    assert_approx_eq!((-0.0f64).round_ties_even(), -0.0f64);
-    assert_approx_eq!((-1.0f64).round_ties_even(), -1.0f64);
-    assert_approx_eq!((-1.3f64).round_ties_even(), -1.0f64);
-    assert_approx_eq!((-1.5f64).round_ties_even(), -2.0f64);
-    assert_approx_eq!((-1.7f64).round_ties_even(), -2.0f64);
+    assert_approx_eq!(f64::round_ties_even(2.5f64), 2.0f64);
+    assert_approx_eq!(f64::round_ties_even(1.0f64), 1.0f64);
+    assert_approx_eq!(f64::round_ties_even(1.3f64), 1.0f64);
+    assert_approx_eq!(f64::round_ties_even(1.5f64), 2.0f64);
+    assert_approx_eq!(f64::round_ties_even(1.7f64), 2.0f64);
+    assert_approx_eq!(f64::round_ties_even(0.0f64), 0.0f64);
+    assert_approx_eq!(f64::round_ties_even(-0.0f64), -0.0f64);
+    assert_approx_eq!(f64::round_ties_even(-1.0f64), -1.0f64);
+    assert_approx_eq!(f64::round_ties_even(-1.3f64), -1.0f64);
+    assert_approx_eq!(f64::round_ties_even(-1.5f64), -2.0f64);
+    assert_approx_eq!(f64::round_ties_even(-1.7f64), -2.0f64);
 }
 
 #[test]
 fn test_trunc() {
-    assert_approx_eq!(1.0f64.trunc(), 1.0f64);
-    assert_approx_eq!(1.3f64.trunc(), 1.0f64);
-    assert_approx_eq!(1.5f64.trunc(), 1.0f64);
-    assert_approx_eq!(1.7f64.trunc(), 1.0f64);
-    assert_approx_eq!(0.0f64.trunc(), 0.0f64);
-    assert_approx_eq!((-0.0f64).trunc(), -0.0f64);
-    assert_approx_eq!((-1.0f64).trunc(), -1.0f64);
-    assert_approx_eq!((-1.3f64).trunc(), -1.0f64);
-    assert_approx_eq!((-1.5f64).trunc(), -1.0f64);
-    assert_approx_eq!((-1.7f64).trunc(), -1.0f64);
+    assert_approx_eq!(f64::trunc(1.0f64), 1.0f64);
+    assert_approx_eq!(f64::trunc(1.3f64), 1.0f64);
+    assert_approx_eq!(f64::trunc(1.5f64), 1.0f64);
+    assert_approx_eq!(f64::trunc(1.7f64), 1.0f64);
+    assert_approx_eq!(f64::trunc(0.0f64), 0.0f64);
+    assert_approx_eq!(f64::trunc(-0.0f64), -0.0f64);
+    assert_approx_eq!(f64::trunc(-1.0f64), -1.0f64);
+    assert_approx_eq!(f64::trunc(-1.3f64), -1.0f64);
+    assert_approx_eq!(f64::trunc(-1.5f64), -1.0f64);
+    assert_approx_eq!(f64::trunc(-1.7f64), -1.0f64);
 }
 
 #[test]
 fn test_fract() {
-    assert_approx_eq!(1.0f64.fract(), 0.0f64);
-    assert_approx_eq!(1.3f64.fract(), 0.3f64);
-    assert_approx_eq!(1.5f64.fract(), 0.5f64);
-    assert_approx_eq!(1.7f64.fract(), 0.7f64);
-    assert_approx_eq!(0.0f64.fract(), 0.0f64);
-    assert_approx_eq!((-0.0f64).fract(), -0.0f64);
-    assert_approx_eq!((-1.0f64).fract(), -0.0f64);
-    assert_approx_eq!((-1.3f64).fract(), -0.3f64);
-    assert_approx_eq!((-1.5f64).fract(), -0.5f64);
-    assert_approx_eq!((-1.7f64).fract(), -0.7f64);
+    assert_approx_eq!(f64::fract(1.0f64), 0.0f64);
+    assert_approx_eq!(f64::fract(1.3f64), 0.3f64);
+    assert_approx_eq!(f64::fract(1.5f64), 0.5f64);
+    assert_approx_eq!(f64::fract(1.7f64), 0.7f64);
+    assert_approx_eq!(f64::fract(0.0f64), 0.0f64);
+    assert_approx_eq!(f64::fract(-0.0f64), -0.0f64);
+    assert_approx_eq!(f64::fract(-1.0f64), -0.0f64);
+    assert_approx_eq!(f64::fract(-1.3f64), -0.3f64);
+    assert_approx_eq!(f64::fract(-1.5f64), -0.5f64);
+    assert_approx_eq!(f64::fract(-1.7f64), -0.7f64);
 }
 
 #[test]
@@ -439,22 +439,6 @@ fn test_powi() {
 }
 
 #[test]
-fn test_powf() {
-    let nan: f64 = f64::NAN;
-    let inf: f64 = f64::INFINITY;
-    let neg_inf: f64 = f64::NEG_INFINITY;
-    assert_eq!(1.0f64.powf(1.0), 1.0);
-    assert_approx_eq!(3.4f64.powf(4.5), 246.408183);
-    assert_approx_eq!(2.7f64.powf(-3.2), 0.041652);
-    assert_approx_eq!((-3.1f64).powf(2.0), 9.61);
-    assert_approx_eq!(5.9f64.powf(-2.0), 0.028727);
-    assert_eq!(8.3f64.powf(0.0), 1.0);
-    assert!(nan.powf(2.0).is_nan());
-    assert_eq!(inf.powf(2.0), inf);
-    assert_eq!(neg_inf.powf(3.0), neg_inf);
-}
-
-#[test]
 fn test_sqrt_domain() {
     assert!(f64::NAN.sqrt().is_nan());
     assert!(f64::NEG_INFINITY.sqrt().is_nan());
@@ -466,99 +450,6 @@ fn test_sqrt_domain() {
 }
 
 #[test]
-fn test_exp() {
-    assert_eq!(1.0, 0.0f64.exp());
-    assert_approx_eq!(2.718282, 1.0f64.exp());
-    assert_approx_eq!(148.413159, 5.0f64.exp());
-
-    let inf: f64 = f64::INFINITY;
-    let neg_inf: f64 = f64::NEG_INFINITY;
-    let nan: f64 = f64::NAN;
-    assert_eq!(inf, inf.exp());
-    assert_eq!(0.0, neg_inf.exp());
-    assert!(nan.exp().is_nan());
-}
-
-#[test]
-fn test_exp2() {
-    assert_eq!(32.0, 5.0f64.exp2());
-    assert_eq!(1.0, 0.0f64.exp2());
-
-    let inf: f64 = f64::INFINITY;
-    let neg_inf: f64 = f64::NEG_INFINITY;
-    let nan: f64 = f64::NAN;
-    assert_eq!(inf, inf.exp2());
-    assert_eq!(0.0, neg_inf.exp2());
-    assert!(nan.exp2().is_nan());
-}
-
-#[test]
-fn test_ln() {
-    let nan: f64 = f64::NAN;
-    let inf: f64 = f64::INFINITY;
-    let neg_inf: f64 = f64::NEG_INFINITY;
-    assert_approx_eq!(1.0f64.exp().ln(), 1.0);
-    assert!(nan.ln().is_nan());
-    assert_eq!(inf.ln(), inf);
-    assert!(neg_inf.ln().is_nan());
-    assert!((-2.3f64).ln().is_nan());
-    assert_eq!((-0.0f64).ln(), neg_inf);
-    assert_eq!(0.0f64.ln(), neg_inf);
-    assert_approx_eq!(4.0f64.ln(), 1.386294);
-}
-
-#[test]
-fn test_log() {
-    let nan: f64 = f64::NAN;
-    let inf: f64 = f64::INFINITY;
-    let neg_inf: f64 = f64::NEG_INFINITY;
-    assert_eq!(10.0f64.log(10.0), 1.0);
-    assert_approx_eq!(2.3f64.log(3.5), 0.664858);
-    assert_eq!(1.0f64.exp().log(1.0f64.exp()), 1.0);
-    assert!(1.0f64.log(1.0).is_nan());
-    assert!(1.0f64.log(-13.9).is_nan());
-    assert!(nan.log(2.3).is_nan());
-    assert_eq!(inf.log(10.0), inf);
-    assert!(neg_inf.log(8.8).is_nan());
-    assert!((-2.3f64).log(0.1).is_nan());
-    assert_eq!((-0.0f64).log(2.0), neg_inf);
-    assert_eq!(0.0f64.log(7.0), neg_inf);
-}
-
-#[test]
-fn test_log2() {
-    let nan: f64 = f64::NAN;
-    let inf: f64 = f64::INFINITY;
-    let neg_inf: f64 = f64::NEG_INFINITY;
-    assert_approx_eq!(10.0f64.log2(), 3.321928);
-    assert_approx_eq!(2.3f64.log2(), 1.201634);
-    assert_approx_eq!(1.0f64.exp().log2(), 1.442695);
-    assert!(nan.log2().is_nan());
-    assert_eq!(inf.log2(), inf);
-    assert!(neg_inf.log2().is_nan());
-    assert!((-2.3f64).log2().is_nan());
-    assert_eq!((-0.0f64).log2(), neg_inf);
-    assert_eq!(0.0f64.log2(), neg_inf);
-}
-
-#[test]
-fn test_log10() {
-    let nan: f64 = f64::NAN;
-    let inf: f64 = f64::INFINITY;
-    let neg_inf: f64 = f64::NEG_INFINITY;
-    assert_eq!(10.0f64.log10(), 1.0);
-    assert_approx_eq!(2.3f64.log10(), 0.361728);
-    assert_approx_eq!(1.0f64.exp().log10(), 0.434294);
-    assert_eq!(1.0f64.log10(), 0.0);
-    assert!(nan.log10().is_nan());
-    assert_eq!(inf.log10(), inf);
-    assert!(neg_inf.log10().is_nan());
-    assert!((-2.3f64).log10().is_nan());
-    assert_eq!((-0.0f64).log10(), neg_inf);
-    assert_eq!(0.0f64.log10(), neg_inf);
-}
-
-#[test]
 fn test_to_degrees() {
     let pi: f64 = consts::PI;
     let nan: f64 = f64::NAN;
@@ -588,134 +479,6 @@ fn test_to_radians() {
 }
 
 #[test]
-fn test_asinh() {
-    assert_eq!(0.0f64.asinh(), 0.0f64);
-    assert_eq!((-0.0f64).asinh(), -0.0f64);
-
-    let inf: f64 = f64::INFINITY;
-    let neg_inf: f64 = f64::NEG_INFINITY;
-    let nan: f64 = f64::NAN;
-    assert_eq!(inf.asinh(), inf);
-    assert_eq!(neg_inf.asinh(), neg_inf);
-    assert!(nan.asinh().is_nan());
-    assert!((-0.0f64).asinh().is_sign_negative());
-    // issue 63271
-    assert_approx_eq!(2.0f64.asinh(), 1.443635475178810342493276740273105f64);
-    assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64);
-    // regression test for the catastrophic cancellation fixed in 72486
-    assert_approx_eq!((-67452098.07139316f64).asinh(), -18.72007542627454439398548429400083);
-
-    // test for low accuracy from issue 104548
-    assert_approx_eq!(60.0f64, 60.0f64.sinh().asinh());
-    // mul needed for approximate comparison to be meaningful
-    assert_approx_eq!(1.0f64, 1e-15f64.sinh().asinh() * 1e15f64);
-}
-
-#[test]
-fn test_acosh() {
-    assert_eq!(1.0f64.acosh(), 0.0f64);
-    assert!(0.999f64.acosh().is_nan());
-
-    let inf: f64 = f64::INFINITY;
-    let neg_inf: f64 = f64::NEG_INFINITY;
-    let nan: f64 = f64::NAN;
-    assert_eq!(inf.acosh(), inf);
-    assert!(neg_inf.acosh().is_nan());
-    assert!(nan.acosh().is_nan());
-    assert_approx_eq!(2.0f64.acosh(), 1.31695789692481670862504634730796844f64);
-    assert_approx_eq!(3.0f64.acosh(), 1.76274717403908605046521864995958461f64);
-
-    // test for low accuracy from issue 104548
-    assert_approx_eq!(60.0f64, 60.0f64.cosh().acosh());
-}
-
-#[test]
-fn test_atanh() {
-    assert_eq!(0.0f64.atanh(), 0.0f64);
-    assert_eq!((-0.0f64).atanh(), -0.0f64);
-
-    let inf: f64 = f64::INFINITY;
-    let neg_inf: f64 = f64::NEG_INFINITY;
-    let nan: f64 = f64::NAN;
-    assert_eq!(1.0f64.atanh(), inf);
-    assert_eq!((-1.0f64).atanh(), neg_inf);
-    assert!(2f64.atanh().atanh().is_nan());
-    assert!((-2f64).atanh().atanh().is_nan());
-    assert!(inf.atanh().is_nan());
-    assert!(neg_inf.atanh().is_nan());
-    assert!(nan.atanh().is_nan());
-    assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64);
-    assert_approx_eq!((-0.5f64).atanh(), -0.54930614433405484569762261846126285f64);
-}
-
-#[test]
-fn test_gamma() {
-    // precision can differ between platforms
-    assert_approx_eq!(1.0f64.gamma(), 1.0f64);
-    assert_approx_eq!(2.0f64.gamma(), 1.0f64);
-    assert_approx_eq!(3.0f64.gamma(), 2.0f64);
-    assert_approx_eq!(4.0f64.gamma(), 6.0f64);
-    assert_approx_eq!(5.0f64.gamma(), 24.0f64);
-    assert_approx_eq!(0.5f64.gamma(), consts::PI.sqrt());
-    assert_approx_eq!((-0.5f64).gamma(), -2.0 * consts::PI.sqrt());
-    assert_eq!(0.0f64.gamma(), f64::INFINITY);
-    assert_eq!((-0.0f64).gamma(), f64::NEG_INFINITY);
-    assert!((-1.0f64).gamma().is_nan());
-    assert!((-2.0f64).gamma().is_nan());
-    assert!(f64::NAN.gamma().is_nan());
-    assert!(f64::NEG_INFINITY.gamma().is_nan());
-    assert_eq!(f64::INFINITY.gamma(), f64::INFINITY);
-    assert_eq!(171.71f64.gamma(), f64::INFINITY);
-}
-
-#[test]
-fn test_ln_gamma() {
-    assert_approx_eq!(1.0f64.ln_gamma().0, 0.0f64);
-    assert_eq!(1.0f64.ln_gamma().1, 1);
-    assert_approx_eq!(2.0f64.ln_gamma().0, 0.0f64);
-    assert_eq!(2.0f64.ln_gamma().1, 1);
-    assert_approx_eq!(3.0f64.ln_gamma().0, 2.0f64.ln());
-    assert_eq!(3.0f64.ln_gamma().1, 1);
-    assert_approx_eq!((-0.5f64).ln_gamma().0, (2.0 * consts::PI.sqrt()).ln());
-    assert_eq!((-0.5f64).ln_gamma().1, -1);
-}
-
-#[test]
-fn test_real_consts() {
-    let pi: f64 = consts::PI;
-    let frac_pi_2: f64 = consts::FRAC_PI_2;
-    let frac_pi_3: f64 = consts::FRAC_PI_3;
-    let frac_pi_4: f64 = consts::FRAC_PI_4;
-    let frac_pi_6: f64 = consts::FRAC_PI_6;
-    let frac_pi_8: f64 = consts::FRAC_PI_8;
-    let frac_1_pi: f64 = consts::FRAC_1_PI;
-    let frac_2_pi: f64 = consts::FRAC_2_PI;
-    let frac_2_sqrtpi: f64 = consts::FRAC_2_SQRT_PI;
-    let sqrt2: f64 = consts::SQRT_2;
-    let frac_1_sqrt2: f64 = consts::FRAC_1_SQRT_2;
-    let e: f64 = consts::E;
-    let log2_e: f64 = consts::LOG2_E;
-    let log10_e: f64 = consts::LOG10_E;
-    let ln_2: f64 = consts::LN_2;
-    let ln_10: f64 = consts::LN_10;
-
-    assert_approx_eq!(frac_pi_2, pi / 2f64);
-    assert_approx_eq!(frac_pi_3, pi / 3f64);
-    assert_approx_eq!(frac_pi_4, pi / 4f64);
-    assert_approx_eq!(frac_pi_6, pi / 6f64);
-    assert_approx_eq!(frac_pi_8, pi / 8f64);
-    assert_approx_eq!(frac_1_pi, 1f64 / pi);
-    assert_approx_eq!(frac_2_pi, 2f64 / pi);
-    assert_approx_eq!(frac_2_sqrtpi, 2f64 / pi.sqrt());
-    assert_approx_eq!(sqrt2, 2f64.sqrt());
-    assert_approx_eq!(frac_1_sqrt2, 1f64 / 2f64.sqrt());
-    assert_approx_eq!(log2_e, e.log2());
-    assert_approx_eq!(log10_e, e.log10());
-    assert_approx_eq!(ln_2, 2f64.ln());
-    assert_approx_eq!(ln_10, 10f64.ln());
-}
-
-#[test]
 fn test_float_bits_conv() {
     assert_eq!((1f64).to_bits(), 0x3ff0000000000000);
     assert_eq!((12.5f64).to_bits(), 0x4029000000000000);
diff --git a/library/coretests/tests/floats/mod.rs b/library/coretests/tests/floats/mod.rs
index 453a2d533ab..7de34271ad0 100644
--- a/library/coretests/tests/floats/mod.rs
+++ b/library/coretests/tests/floats/mod.rs
@@ -1,7 +1,3 @@
-#![feature(f16, f128, float_algebraic, float_gamma, float_minimum_maximum)]
-#![feature(cfg_target_has_reliable_f16_f128)]
-#![expect(internal_features)] // for reliable_f16_f128
-
 use std::fmt;
 use std::ops::{Add, Div, Mul, Rem, Sub};
 
diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs
index acea0b2a035..b98e52718f6 100644
--- a/library/coretests/tests/lib.rs
+++ b/library/coretests/tests/lib.rs
@@ -12,10 +12,12 @@
 #![feature(async_iterator)]
 #![feature(bigint_helper_methods)]
 #![feature(bstr)]
+#![feature(cfg_target_has_reliable_f16_f128)]
 #![feature(char_max_len)]
 #![feature(clone_to_uninit)]
 #![feature(const_eval_select)]
 #![feature(const_trait_impl)]
+#![feature(core_float_math)]
 #![feature(core_intrinsics)]
 #![feature(core_intrinsics_fallbacks)]
 #![feature(core_io_borrowed_buf)]
@@ -29,6 +31,10 @@
 #![feature(exact_size_is_empty)]
 #![feature(extend_one)]
 #![feature(extern_types)]
+#![feature(f128)]
+#![feature(f16)]
+#![feature(float_algebraic)]
+#![feature(float_gamma)]
 #![feature(float_minimum_maximum)]
 #![feature(flt2dec)]
 #![feature(fmt_internals)]
diff --git a/library/std/tests/floats/f128.rs b/library/std/tests/floats/f128.rs
new file mode 100644
index 00000000000..e7c90faa05c
--- /dev/null
+++ b/library/std/tests/floats/f128.rs
@@ -0,0 +1,321 @@
+// FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy
+#![cfg(target_has_reliable_f128)]
+
+use std::f128::consts;
+use std::ops::{Add, Div, Mul, Sub};
+
+// Note these tolerances make sense around zero, but not for more extreme exponents.
+
+/// Default tolerances. Works for values that should be near precise but not exact. Roughly
+/// the precision carried by `100 * 100`.
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f128_math)]
+const TOL: f128 = 1e-12;
+
+/// For operations that are near exact, usually not involving math of different
+/// signs.
+const TOL_PRECISE: f128 = 1e-28;
+
+/// Tolerances for math that is allowed to be imprecise, usually due to multiple chained
+/// operations.
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f128_math)]
+const TOL_IMPR: f128 = 1e-10;
+
+/// Compare by representation
+#[allow(unused_macros)]
+macro_rules! assert_f128_biteq {
+    ($a:expr, $b:expr) => {
+        let (l, r): (&f128, &f128) = (&$a, &$b);
+        let lb = l.to_bits();
+        let rb = r.to_bits();
+        assert_eq!(lb, rb, "float {l:?} is not bitequal to {r:?}.\na: {lb:#034x}\nb: {rb:#034x}");
+    };
+}
+
+#[test]
+fn test_num_f128() {
+    // FIXME(f16_f128): replace with a `test_num` call once the required `fmodl`/`fmodf128`
+    // function is available on all platforms.
+    let ten = 10f128;
+    let two = 2f128;
+    assert_eq!(ten.add(two), ten + two);
+    assert_eq!(ten.sub(two), ten - two);
+    assert_eq!(ten.mul(two), ten * two);
+    assert_eq!(ten.div(two), ten / two);
+}
+
+// Many math functions allow for less accurate results, so the next tolerance up is used
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f128_math)]
+fn test_powf() {
+    let nan: f128 = f128::NAN;
+    let inf: f128 = f128::INFINITY;
+    let neg_inf: f128 = f128::NEG_INFINITY;
+    assert_eq!(1.0f128.powf(1.0), 1.0);
+    assert_approx_eq!(3.4f128.powf(4.5), 246.40818323761892815995637964326426756, TOL_IMPR);
+    assert_approx_eq!(2.7f128.powf(-3.2), 0.041652009108526178281070304373500889273, TOL_IMPR);
+    assert_approx_eq!((-3.1f128).powf(2.0), 9.6100000000000005506706202140776519387, TOL_IMPR);
+    assert_approx_eq!(5.9f128.powf(-2.0), 0.028727377190462507313100483690639638451, TOL_IMPR);
+    assert_eq!(8.3f128.powf(0.0), 1.0);
+    assert!(nan.powf(2.0).is_nan());
+    assert_eq!(inf.powf(2.0), inf);
+    assert_eq!(neg_inf.powf(3.0), neg_inf);
+}
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f128_math)]
+fn test_exp() {
+    assert_eq!(1.0, 0.0f128.exp());
+    assert_approx_eq!(consts::E, 1.0f128.exp(), TOL);
+    assert_approx_eq!(148.41315910257660342111558004055227962348775, 5.0f128.exp(), TOL);
+
+    let inf: f128 = f128::INFINITY;
+    let neg_inf: f128 = f128::NEG_INFINITY;
+    let nan: f128 = f128::NAN;
+    assert_eq!(inf, inf.exp());
+    assert_eq!(0.0, neg_inf.exp());
+    assert!(nan.exp().is_nan());
+}
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f128_math)]
+fn test_exp2() {
+    assert_eq!(32.0, 5.0f128.exp2());
+    assert_eq!(1.0, 0.0f128.exp2());
+
+    let inf: f128 = f128::INFINITY;
+    let neg_inf: f128 = f128::NEG_INFINITY;
+    let nan: f128 = f128::NAN;
+    assert_eq!(inf, inf.exp2());
+    assert_eq!(0.0, neg_inf.exp2());
+    assert!(nan.exp2().is_nan());
+}
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f128_math)]
+fn test_ln() {
+    let nan: f128 = f128::NAN;
+    let inf: f128 = f128::INFINITY;
+    let neg_inf: f128 = f128::NEG_INFINITY;
+    assert_approx_eq!(1.0f128.exp().ln(), 1.0, TOL);
+    assert!(nan.ln().is_nan());
+    assert_eq!(inf.ln(), inf);
+    assert!(neg_inf.ln().is_nan());
+    assert!((-2.3f128).ln().is_nan());
+    assert_eq!((-0.0f128).ln(), neg_inf);
+    assert_eq!(0.0f128.ln(), neg_inf);
+    assert_approx_eq!(4.0f128.ln(), 1.3862943611198906188344642429163531366, TOL);
+}
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f128_math)]
+fn test_log() {
+    let nan: f128 = f128::NAN;
+    let inf: f128 = f128::INFINITY;
+    let neg_inf: f128 = f128::NEG_INFINITY;
+    assert_eq!(10.0f128.log(10.0), 1.0);
+    assert_approx_eq!(2.3f128.log(3.5), 0.66485771361478710036766645911922010272, TOL);
+    assert_eq!(1.0f128.exp().log(1.0f128.exp()), 1.0);
+    assert!(1.0f128.log(1.0).is_nan());
+    assert!(1.0f128.log(-13.9).is_nan());
+    assert!(nan.log(2.3).is_nan());
+    assert_eq!(inf.log(10.0), inf);
+    assert!(neg_inf.log(8.8).is_nan());
+    assert!((-2.3f128).log(0.1).is_nan());
+    assert_eq!((-0.0f128).log(2.0), neg_inf);
+    assert_eq!(0.0f128.log(7.0), neg_inf);
+}
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f128_math)]
+fn test_log2() {
+    let nan: f128 = f128::NAN;
+    let inf: f128 = f128::INFINITY;
+    let neg_inf: f128 = f128::NEG_INFINITY;
+    assert_approx_eq!(10.0f128.log2(), 3.32192809488736234787031942948939017, TOL);
+    assert_approx_eq!(2.3f128.log2(), 1.2016338611696504130002982471978765921, TOL);
+    assert_approx_eq!(1.0f128.exp().log2(), 1.4426950408889634073599246810018921381, TOL);
+    assert!(nan.log2().is_nan());
+    assert_eq!(inf.log2(), inf);
+    assert!(neg_inf.log2().is_nan());
+    assert!((-2.3f128).log2().is_nan());
+    assert_eq!((-0.0f128).log2(), neg_inf);
+    assert_eq!(0.0f128.log2(), neg_inf);
+}
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f128_math)]
+fn test_log10() {
+    let nan: f128 = f128::NAN;
+    let inf: f128 = f128::INFINITY;
+    let neg_inf: f128 = f128::NEG_INFINITY;
+    assert_eq!(10.0f128.log10(), 1.0);
+    assert_approx_eq!(2.3f128.log10(), 0.36172783601759284532595218865859309898, TOL);
+    assert_approx_eq!(1.0f128.exp().log10(), 0.43429448190325182765112891891660508222, TOL);
+    assert_eq!(1.0f128.log10(), 0.0);
+    assert!(nan.log10().is_nan());
+    assert_eq!(inf.log10(), inf);
+    assert!(neg_inf.log10().is_nan());
+    assert!((-2.3f128).log10().is_nan());
+    assert_eq!((-0.0f128).log10(), neg_inf);
+    assert_eq!(0.0f128.log10(), neg_inf);
+}
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f128_math)]
+fn test_asinh() {
+    // Lower accuracy results are allowed, use increased tolerances
+    assert_eq!(0.0f128.asinh(), 0.0f128);
+    assert_eq!((-0.0f128).asinh(), -0.0f128);
+
+    let inf: f128 = f128::INFINITY;
+    let neg_inf: f128 = f128::NEG_INFINITY;
+    let nan: f128 = f128::NAN;
+    assert_eq!(inf.asinh(), inf);
+    assert_eq!(neg_inf.asinh(), neg_inf);
+    assert!(nan.asinh().is_nan());
+    assert!((-0.0f128).asinh().is_sign_negative());
+
+    // issue 63271
+    assert_approx_eq!(2.0f128.asinh(), 1.443635475178810342493276740273105f128, TOL_IMPR);
+    assert_approx_eq!((-2.0f128).asinh(), -1.443635475178810342493276740273105f128, TOL_IMPR);
+    // regression test for the catastrophic cancellation fixed in 72486
+    assert_approx_eq!(
+        (-67452098.07139316f128).asinh(),
+        -18.720075426274544393985484294000831757220,
+        TOL_IMPR
+    );
+
+    // test for low accuracy from issue 104548
+    assert_approx_eq!(60.0f128, 60.0f128.sinh().asinh(), TOL_IMPR);
+    // mul needed for approximate comparison to be meaningful
+    assert_approx_eq!(1.0f128, 1e-15f128.sinh().asinh() * 1e15f128, TOL_IMPR);
+}
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f128_math)]
+fn test_acosh() {
+    assert_eq!(1.0f128.acosh(), 0.0f128);
+    assert!(0.999f128.acosh().is_nan());
+
+    let inf: f128 = f128::INFINITY;
+    let neg_inf: f128 = f128::NEG_INFINITY;
+    let nan: f128 = f128::NAN;
+    assert_eq!(inf.acosh(), inf);
+    assert!(neg_inf.acosh().is_nan());
+    assert!(nan.acosh().is_nan());
+    assert_approx_eq!(2.0f128.acosh(), 1.31695789692481670862504634730796844f128, TOL_IMPR);
+    assert_approx_eq!(3.0f128.acosh(), 1.76274717403908605046521864995958461f128, TOL_IMPR);
+
+    // test for low accuracy from issue 104548
+    assert_approx_eq!(60.0f128, 60.0f128.cosh().acosh(), TOL_IMPR);
+}
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f128_math)]
+fn test_atanh() {
+    assert_eq!(0.0f128.atanh(), 0.0f128);
+    assert_eq!((-0.0f128).atanh(), -0.0f128);
+
+    let inf: f128 = f128::INFINITY;
+    let neg_inf: f128 = f128::NEG_INFINITY;
+    let nan: f128 = f128::NAN;
+    assert_eq!(1.0f128.atanh(), inf);
+    assert_eq!((-1.0f128).atanh(), neg_inf);
+    assert!(2f128.atanh().atanh().is_nan());
+    assert!((-2f128).atanh().atanh().is_nan());
+    assert!(inf.atanh().is_nan());
+    assert!(neg_inf.atanh().is_nan());
+    assert!(nan.atanh().is_nan());
+    assert_approx_eq!(0.5f128.atanh(), 0.54930614433405484569762261846126285f128, TOL_IMPR);
+    assert_approx_eq!((-0.5f128).atanh(), -0.54930614433405484569762261846126285f128, TOL_IMPR);
+}
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f128_math)]
+fn test_gamma() {
+    // precision can differ among platforms
+    assert_approx_eq!(1.0f128.gamma(), 1.0f128, TOL_IMPR);
+    assert_approx_eq!(2.0f128.gamma(), 1.0f128, TOL_IMPR);
+    assert_approx_eq!(3.0f128.gamma(), 2.0f128, TOL_IMPR);
+    assert_approx_eq!(4.0f128.gamma(), 6.0f128, TOL_IMPR);
+    assert_approx_eq!(5.0f128.gamma(), 24.0f128, TOL_IMPR);
+    assert_approx_eq!(0.5f128.gamma(), consts::PI.sqrt(), TOL_IMPR);
+    assert_approx_eq!((-0.5f128).gamma(), -2.0 * consts::PI.sqrt(), TOL_IMPR);
+    assert_eq!(0.0f128.gamma(), f128::INFINITY);
+    assert_eq!((-0.0f128).gamma(), f128::NEG_INFINITY);
+    assert!((-1.0f128).gamma().is_nan());
+    assert!((-2.0f128).gamma().is_nan());
+    assert!(f128::NAN.gamma().is_nan());
+    assert!(f128::NEG_INFINITY.gamma().is_nan());
+    assert_eq!(f128::INFINITY.gamma(), f128::INFINITY);
+    assert_eq!(1760.9f128.gamma(), f128::INFINITY);
+}
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f128_math)]
+fn test_ln_gamma() {
+    assert_approx_eq!(1.0f128.ln_gamma().0, 0.0f128, TOL_IMPR);
+    assert_eq!(1.0f128.ln_gamma().1, 1);
+    assert_approx_eq!(2.0f128.ln_gamma().0, 0.0f128, TOL_IMPR);
+    assert_eq!(2.0f128.ln_gamma().1, 1);
+    assert_approx_eq!(3.0f128.ln_gamma().0, 2.0f128.ln(), TOL_IMPR);
+    assert_eq!(3.0f128.ln_gamma().1, 1);
+    assert_approx_eq!((-0.5f128).ln_gamma().0, (2.0 * consts::PI.sqrt()).ln(), TOL_IMPR);
+    assert_eq!((-0.5f128).ln_gamma().1, -1);
+}
+
+#[test]
+fn test_real_consts() {
+    let pi: f128 = consts::PI;
+    let frac_pi_2: f128 = consts::FRAC_PI_2;
+    let frac_pi_3: f128 = consts::FRAC_PI_3;
+    let frac_pi_4: f128 = consts::FRAC_PI_4;
+    let frac_pi_6: f128 = consts::FRAC_PI_6;
+    let frac_pi_8: f128 = consts::FRAC_PI_8;
+    let frac_1_pi: f128 = consts::FRAC_1_PI;
+    let frac_2_pi: f128 = consts::FRAC_2_PI;
+
+    assert_approx_eq!(frac_pi_2, pi / 2f128, TOL_PRECISE);
+    assert_approx_eq!(frac_pi_3, pi / 3f128, TOL_PRECISE);
+    assert_approx_eq!(frac_pi_4, pi / 4f128, TOL_PRECISE);
+    assert_approx_eq!(frac_pi_6, pi / 6f128, TOL_PRECISE);
+    assert_approx_eq!(frac_pi_8, pi / 8f128, TOL_PRECISE);
+    assert_approx_eq!(frac_1_pi, 1f128 / pi, TOL_PRECISE);
+    assert_approx_eq!(frac_2_pi, 2f128 / pi, TOL_PRECISE);
+
+    #[cfg(not(miri))]
+    #[cfg(target_has_reliable_f128_math)]
+    {
+        let frac_2_sqrtpi: f128 = consts::FRAC_2_SQRT_PI;
+        let sqrt2: f128 = consts::SQRT_2;
+        let frac_1_sqrt2: f128 = consts::FRAC_1_SQRT_2;
+        let e: f128 = consts::E;
+        let log2_e: f128 = consts::LOG2_E;
+        let log10_e: f128 = consts::LOG10_E;
+        let ln_2: f128 = consts::LN_2;
+        let ln_10: f128 = consts::LN_10;
+
+        assert_approx_eq!(frac_2_sqrtpi, 2f128 / pi.sqrt(), TOL_PRECISE);
+        assert_approx_eq!(sqrt2, 2f128.sqrt(), TOL_PRECISE);
+        assert_approx_eq!(frac_1_sqrt2, 1f128 / 2f128.sqrt(), TOL_PRECISE);
+        assert_approx_eq!(log2_e, e.log2(), TOL_PRECISE);
+        assert_approx_eq!(log10_e, e.log10(), TOL_PRECISE);
+        assert_approx_eq!(ln_2, 2f128.ln(), TOL_PRECISE);
+        assert_approx_eq!(ln_10, 10f128.ln(), TOL_PRECISE);
+    }
+}
diff --git a/library/std/tests/floats/f16.rs b/library/std/tests/floats/f16.rs
new file mode 100644
index 00000000000..0f8b4138d22
--- /dev/null
+++ b/library/std/tests/floats/f16.rs
@@ -0,0 +1,300 @@
+// FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy
+#![cfg(target_has_reliable_f16)]
+
+use std::f16::consts;
+
+/// Tolerance for results on the order of 10.0e-2
+#[allow(unused)]
+const TOL_N2: f16 = 0.0001;
+
+/// Tolerance for results on the order of 10.0e+0
+#[allow(unused)]
+const TOL_0: f16 = 0.01;
+
+/// Tolerance for results on the order of 10.0e+2
+#[allow(unused)]
+const TOL_P2: f16 = 0.5;
+
+/// Tolerance for results on the order of 10.0e+4
+#[allow(unused)]
+const TOL_P4: f16 = 10.0;
+
+/// Compare by representation
+#[allow(unused_macros)]
+macro_rules! assert_f16_biteq {
+    ($a:expr, $b:expr) => {
+        let (l, r): (&f16, &f16) = (&$a, &$b);
+        let lb = l.to_bits();
+        let rb = r.to_bits();
+        assert_eq!(lb, rb, "float {l:?} ({lb:#04x}) is not bitequal to {r:?} ({rb:#04x})");
+    };
+}
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f16_math)]
+fn test_powf() {
+    let nan: f16 = f16::NAN;
+    let inf: f16 = f16::INFINITY;
+    let neg_inf: f16 = f16::NEG_INFINITY;
+    assert_eq!(1.0f16.powf(1.0), 1.0);
+    assert_approx_eq!(3.4f16.powf(4.5), 246.408183, TOL_P2);
+    assert_approx_eq!(2.7f16.powf(-3.2), 0.041652, TOL_N2);
+    assert_approx_eq!((-3.1f16).powf(2.0), 9.61, TOL_P2);
+    assert_approx_eq!(5.9f16.powf(-2.0), 0.028727, TOL_N2);
+    assert_eq!(8.3f16.powf(0.0), 1.0);
+    assert!(nan.powf(2.0).is_nan());
+    assert_eq!(inf.powf(2.0), inf);
+    assert_eq!(neg_inf.powf(3.0), neg_inf);
+}
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f16_math)]
+fn test_exp() {
+    assert_eq!(1.0, 0.0f16.exp());
+    assert_approx_eq!(2.718282, 1.0f16.exp(), TOL_0);
+    assert_approx_eq!(148.413159, 5.0f16.exp(), TOL_0);
+
+    let inf: f16 = f16::INFINITY;
+    let neg_inf: f16 = f16::NEG_INFINITY;
+    let nan: f16 = f16::NAN;
+    assert_eq!(inf, inf.exp());
+    assert_eq!(0.0, neg_inf.exp());
+    assert!(nan.exp().is_nan());
+}
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f16_math)]
+fn test_exp2() {
+    assert_eq!(32.0, 5.0f16.exp2());
+    assert_eq!(1.0, 0.0f16.exp2());
+
+    let inf: f16 = f16::INFINITY;
+    let neg_inf: f16 = f16::NEG_INFINITY;
+    let nan: f16 = f16::NAN;
+    assert_eq!(inf, inf.exp2());
+    assert_eq!(0.0, neg_inf.exp2());
+    assert!(nan.exp2().is_nan());
+}
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f16_math)]
+fn test_ln() {
+    let nan: f16 = f16::NAN;
+    let inf: f16 = f16::INFINITY;
+    let neg_inf: f16 = f16::NEG_INFINITY;
+    assert_approx_eq!(1.0f16.exp().ln(), 1.0, TOL_0);
+    assert!(nan.ln().is_nan());
+    assert_eq!(inf.ln(), inf);
+    assert!(neg_inf.ln().is_nan());
+    assert!((-2.3f16).ln().is_nan());
+    assert_eq!((-0.0f16).ln(), neg_inf);
+    assert_eq!(0.0f16.ln(), neg_inf);
+    assert_approx_eq!(4.0f16.ln(), 1.386294, TOL_0);
+}
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f16_math)]
+fn test_log() {
+    let nan: f16 = f16::NAN;
+    let inf: f16 = f16::INFINITY;
+    let neg_inf: f16 = f16::NEG_INFINITY;
+    assert_eq!(10.0f16.log(10.0), 1.0);
+    assert_approx_eq!(2.3f16.log(3.5), 0.664858, TOL_0);
+    assert_eq!(1.0f16.exp().log(1.0f16.exp()), 1.0);
+    assert!(1.0f16.log(1.0).is_nan());
+    assert!(1.0f16.log(-13.9).is_nan());
+    assert!(nan.log(2.3).is_nan());
+    assert_eq!(inf.log(10.0), inf);
+    assert!(neg_inf.log(8.8).is_nan());
+    assert!((-2.3f16).log(0.1).is_nan());
+    assert_eq!((-0.0f16).log(2.0), neg_inf);
+    assert_eq!(0.0f16.log(7.0), neg_inf);
+}
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f16_math)]
+fn test_log2() {
+    let nan: f16 = f16::NAN;
+    let inf: f16 = f16::INFINITY;
+    let neg_inf: f16 = f16::NEG_INFINITY;
+    assert_approx_eq!(10.0f16.log2(), 3.321928, TOL_0);
+    assert_approx_eq!(2.3f16.log2(), 1.201634, TOL_0);
+    assert_approx_eq!(1.0f16.exp().log2(), 1.442695, TOL_0);
+    assert!(nan.log2().is_nan());
+    assert_eq!(inf.log2(), inf);
+    assert!(neg_inf.log2().is_nan());
+    assert!((-2.3f16).log2().is_nan());
+    assert_eq!((-0.0f16).log2(), neg_inf);
+    assert_eq!(0.0f16.log2(), neg_inf);
+}
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f16_math)]
+fn test_log10() {
+    let nan: f16 = f16::NAN;
+    let inf: f16 = f16::INFINITY;
+    let neg_inf: f16 = f16::NEG_INFINITY;
+    assert_eq!(10.0f16.log10(), 1.0);
+    assert_approx_eq!(2.3f16.log10(), 0.361728, TOL_0);
+    assert_approx_eq!(1.0f16.exp().log10(), 0.434294, TOL_0);
+    assert_eq!(1.0f16.log10(), 0.0);
+    assert!(nan.log10().is_nan());
+    assert_eq!(inf.log10(), inf);
+    assert!(neg_inf.log10().is_nan());
+    assert!((-2.3f16).log10().is_nan());
+    assert_eq!((-0.0f16).log10(), neg_inf);
+    assert_eq!(0.0f16.log10(), neg_inf);
+}
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f16_math)]
+fn test_asinh() {
+    assert_eq!(0.0f16.asinh(), 0.0f16);
+    assert_eq!((-0.0f16).asinh(), -0.0f16);
+
+    let inf: f16 = f16::INFINITY;
+    let neg_inf: f16 = f16::NEG_INFINITY;
+    let nan: f16 = f16::NAN;
+    assert_eq!(inf.asinh(), inf);
+    assert_eq!(neg_inf.asinh(), neg_inf);
+    assert!(nan.asinh().is_nan());
+    assert!((-0.0f16).asinh().is_sign_negative());
+    // issue 63271
+    assert_approx_eq!(2.0f16.asinh(), 1.443635475178810342493276740273105f16, TOL_0);
+    assert_approx_eq!((-2.0f16).asinh(), -1.443635475178810342493276740273105f16, TOL_0);
+    // regression test for the catastrophic cancellation fixed in 72486
+    assert_approx_eq!((-200.0f16).asinh(), -5.991470797049389, TOL_0);
+
+    // test for low accuracy from issue 104548
+    assert_approx_eq!(10.0f16, 10.0f16.sinh().asinh(), TOL_0);
+    // mul needed for approximate comparison to be meaningful
+    assert_approx_eq!(1.0f16, 1e-3f16.sinh().asinh() * 1e3f16, TOL_0);
+}
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f16_math)]
+fn test_acosh() {
+    assert_eq!(1.0f16.acosh(), 0.0f16);
+    assert!(0.999f16.acosh().is_nan());
+
+    let inf: f16 = f16::INFINITY;
+    let neg_inf: f16 = f16::NEG_INFINITY;
+    let nan: f16 = f16::NAN;
+    assert_eq!(inf.acosh(), inf);
+    assert!(neg_inf.acosh().is_nan());
+    assert!(nan.acosh().is_nan());
+    assert_approx_eq!(2.0f16.acosh(), 1.31695789692481670862504634730796844f16, TOL_0);
+    assert_approx_eq!(3.0f16.acosh(), 1.76274717403908605046521864995958461f16, TOL_0);
+
+    // test for low accuracy from issue 104548
+    assert_approx_eq!(10.0f16, 10.0f16.cosh().acosh(), TOL_P2);
+}
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f16_math)]
+fn test_atanh() {
+    assert_eq!(0.0f16.atanh(), 0.0f16);
+    assert_eq!((-0.0f16).atanh(), -0.0f16);
+
+    let inf: f16 = f16::INFINITY;
+    let neg_inf: f16 = f16::NEG_INFINITY;
+    let nan: f16 = f16::NAN;
+    assert_eq!(1.0f16.atanh(), inf);
+    assert_eq!((-1.0f16).atanh(), neg_inf);
+    assert!(2f16.atanh().atanh().is_nan());
+    assert!((-2f16).atanh().atanh().is_nan());
+    assert!(inf.atanh().is_nan());
+    assert!(neg_inf.atanh().is_nan());
+    assert!(nan.atanh().is_nan());
+    assert_approx_eq!(0.5f16.atanh(), 0.54930614433405484569762261846126285f16, TOL_0);
+    assert_approx_eq!((-0.5f16).atanh(), -0.54930614433405484569762261846126285f16, TOL_0);
+}
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f16_math)]
+fn test_gamma() {
+    // precision can differ among platforms
+    assert_approx_eq!(1.0f16.gamma(), 1.0f16, TOL_0);
+    assert_approx_eq!(2.0f16.gamma(), 1.0f16, TOL_0);
+    assert_approx_eq!(3.0f16.gamma(), 2.0f16, TOL_0);
+    assert_approx_eq!(4.0f16.gamma(), 6.0f16, TOL_0);
+    assert_approx_eq!(5.0f16.gamma(), 24.0f16, TOL_0);
+    assert_approx_eq!(0.5f16.gamma(), consts::PI.sqrt(), TOL_0);
+    assert_approx_eq!((-0.5f16).gamma(), -2.0 * consts::PI.sqrt(), TOL_0);
+    assert_eq!(0.0f16.gamma(), f16::INFINITY);
+    assert_eq!((-0.0f16).gamma(), f16::NEG_INFINITY);
+    assert!((-1.0f16).gamma().is_nan());
+    assert!((-2.0f16).gamma().is_nan());
+    assert!(f16::NAN.gamma().is_nan());
+    assert!(f16::NEG_INFINITY.gamma().is_nan());
+    assert_eq!(f16::INFINITY.gamma(), f16::INFINITY);
+    assert_eq!(171.71f16.gamma(), f16::INFINITY);
+}
+
+#[test]
+#[cfg(not(miri))]
+#[cfg(target_has_reliable_f16_math)]
+fn test_ln_gamma() {
+    assert_approx_eq!(1.0f16.ln_gamma().0, 0.0f16, TOL_0);
+    assert_eq!(1.0f16.ln_gamma().1, 1);
+    assert_approx_eq!(2.0f16.ln_gamma().0, 0.0f16, TOL_0);
+    assert_eq!(2.0f16.ln_gamma().1, 1);
+    assert_approx_eq!(3.0f16.ln_gamma().0, 2.0f16.ln(), TOL_0);
+    assert_eq!(3.0f16.ln_gamma().1, 1);
+    assert_approx_eq!((-0.5f16).ln_gamma().0, (2.0 * consts::PI.sqrt()).ln(), TOL_0);
+    assert_eq!((-0.5f16).ln_gamma().1, -1);
+}
+
+#[test]
+fn test_real_consts() {
+    // FIXME(f16_f128): add math tests when available
+
+    let pi: f16 = consts::PI;
+    let frac_pi_2: f16 = consts::FRAC_PI_2;
+    let frac_pi_3: f16 = consts::FRAC_PI_3;
+    let frac_pi_4: f16 = consts::FRAC_PI_4;
+    let frac_pi_6: f16 = consts::FRAC_PI_6;
+    let frac_pi_8: f16 = consts::FRAC_PI_8;
+    let frac_1_pi: f16 = consts::FRAC_1_PI;
+    let frac_2_pi: f16 = consts::FRAC_2_PI;
+
+    assert_approx_eq!(frac_pi_2, pi / 2f16, TOL_0);
+    assert_approx_eq!(frac_pi_3, pi / 3f16, TOL_0);
+    assert_approx_eq!(frac_pi_4, pi / 4f16, TOL_0);
+    assert_approx_eq!(frac_pi_6, pi / 6f16, TOL_0);
+    assert_approx_eq!(frac_pi_8, pi / 8f16, TOL_0);
+    assert_approx_eq!(frac_1_pi, 1f16 / pi, TOL_0);
+    assert_approx_eq!(frac_2_pi, 2f16 / pi, TOL_0);
+
+    #[cfg(not(miri))]
+    #[cfg(target_has_reliable_f16_math)]
+    {
+        let frac_2_sqrtpi: f16 = consts::FRAC_2_SQRT_PI;
+        let sqrt2: f16 = consts::SQRT_2;
+        let frac_1_sqrt2: f16 = consts::FRAC_1_SQRT_2;
+        let e: f16 = consts::E;
+        let log2_e: f16 = consts::LOG2_E;
+        let log10_e: f16 = consts::LOG10_E;
+        let ln_2: f16 = consts::LN_2;
+        let ln_10: f16 = consts::LN_10;
+
+        assert_approx_eq!(frac_2_sqrtpi, 2f16 / pi.sqrt(), TOL_0);
+        assert_approx_eq!(sqrt2, 2f16.sqrt(), TOL_0);
+        assert_approx_eq!(frac_1_sqrt2, 1f16 / 2f16.sqrt(), TOL_0);
+        assert_approx_eq!(log2_e, e.log2(), TOL_0);
+        assert_approx_eq!(log10_e, e.log10(), TOL_0);
+        assert_approx_eq!(ln_2, 2f16.ln(), TOL_0);
+        assert_approx_eq!(ln_10, 10f16.ln(), TOL_0);
+    }
+}
diff --git a/library/std/tests/floats/f32.rs b/library/std/tests/floats/f32.rs
new file mode 100644
index 00000000000..e54f227bb77
--- /dev/null
+++ b/library/std/tests/floats/f32.rs
@@ -0,0 +1,253 @@
+use std::f32::consts;
+
+#[allow(unused_macros)]
+macro_rules! assert_f32_biteq {
+    ($left : expr, $right : expr) => {
+        let l: &f32 = &$left;
+        let r: &f32 = &$right;
+        let lb = l.to_bits();
+        let rb = r.to_bits();
+        assert_eq!(lb, rb, "float {l} ({lb:#010x}) is not bitequal to {r} ({rb:#010x})");
+    };
+}
+
+#[test]
+fn test_powf() {
+    let nan: f32 = f32::NAN;
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    assert_eq!(1.0f32.powf(1.0), 1.0);
+    assert_approx_eq!(3.4f32.powf(4.5), 246.408218);
+    assert_approx_eq!(2.7f32.powf(-3.2), 0.041652);
+    assert_approx_eq!((-3.1f32).powf(2.0), 9.61);
+    assert_approx_eq!(5.9f32.powf(-2.0), 0.028727);
+    assert_eq!(8.3f32.powf(0.0), 1.0);
+    assert!(nan.powf(2.0).is_nan());
+    assert_eq!(inf.powf(2.0), inf);
+    assert_eq!(neg_inf.powf(3.0), neg_inf);
+}
+
+#[test]
+fn test_exp() {
+    assert_eq!(1.0, 0.0f32.exp());
+    assert_approx_eq!(2.718282, 1.0f32.exp());
+    assert_approx_eq!(148.413162, 5.0f32.exp());
+
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    let nan: f32 = f32::NAN;
+    assert_eq!(inf, inf.exp());
+    assert_eq!(0.0, neg_inf.exp());
+    assert!(nan.exp().is_nan());
+}
+
+#[test]
+fn test_exp2() {
+    assert_eq!(32.0, 5.0f32.exp2());
+    assert_eq!(1.0, 0.0f32.exp2());
+
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    let nan: f32 = f32::NAN;
+    assert_eq!(inf, inf.exp2());
+    assert_eq!(0.0, neg_inf.exp2());
+    assert!(nan.exp2().is_nan());
+}
+
+#[test]
+fn test_ln() {
+    let nan: f32 = f32::NAN;
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    assert_approx_eq!(1.0f32.exp().ln(), 1.0);
+    assert!(nan.ln().is_nan());
+    assert_eq!(inf.ln(), inf);
+    assert!(neg_inf.ln().is_nan());
+    assert!((-2.3f32).ln().is_nan());
+    assert_eq!((-0.0f32).ln(), neg_inf);
+    assert_eq!(0.0f32.ln(), neg_inf);
+    assert_approx_eq!(4.0f32.ln(), 1.386294);
+}
+
+#[test]
+fn test_log() {
+    let nan: f32 = f32::NAN;
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    assert_eq!(10.0f32.log(10.0), 1.0);
+    assert_approx_eq!(2.3f32.log(3.5), 0.664858);
+    assert_eq!(1.0f32.exp().log(1.0f32.exp()), 1.0);
+    assert!(1.0f32.log(1.0).is_nan());
+    assert!(1.0f32.log(-13.9).is_nan());
+    assert!(nan.log(2.3).is_nan());
+    assert_eq!(inf.log(10.0), inf);
+    assert!(neg_inf.log(8.8).is_nan());
+    assert!((-2.3f32).log(0.1).is_nan());
+    assert_eq!((-0.0f32).log(2.0), neg_inf);
+    assert_eq!(0.0f32.log(7.0), neg_inf);
+}
+
+#[test]
+fn test_log2() {
+    let nan: f32 = f32::NAN;
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    assert_approx_eq!(10.0f32.log2(), 3.321928);
+    assert_approx_eq!(2.3f32.log2(), 1.201634);
+    assert_approx_eq!(1.0f32.exp().log2(), 1.442695);
+    assert!(nan.log2().is_nan());
+    assert_eq!(inf.log2(), inf);
+    assert!(neg_inf.log2().is_nan());
+    assert!((-2.3f32).log2().is_nan());
+    assert_eq!((-0.0f32).log2(), neg_inf);
+    assert_eq!(0.0f32.log2(), neg_inf);
+}
+
+#[test]
+fn test_log10() {
+    let nan: f32 = f32::NAN;
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    assert_eq!(10.0f32.log10(), 1.0);
+    assert_approx_eq!(2.3f32.log10(), 0.361728);
+    assert_approx_eq!(1.0f32.exp().log10(), 0.434294);
+    assert_eq!(1.0f32.log10(), 0.0);
+    assert!(nan.log10().is_nan());
+    assert_eq!(inf.log10(), inf);
+    assert!(neg_inf.log10().is_nan());
+    assert!((-2.3f32).log10().is_nan());
+    assert_eq!((-0.0f32).log10(), neg_inf);
+    assert_eq!(0.0f32.log10(), neg_inf);
+}
+
+#[test]
+fn test_asinh() {
+    assert_eq!(0.0f32.asinh(), 0.0f32);
+    assert_eq!((-0.0f32).asinh(), -0.0f32);
+
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    let nan: f32 = f32::NAN;
+    assert_eq!(inf.asinh(), inf);
+    assert_eq!(neg_inf.asinh(), neg_inf);
+    assert!(nan.asinh().is_nan());
+    assert!((-0.0f32).asinh().is_sign_negative()); // issue 63271
+    assert_approx_eq!(2.0f32.asinh(), 1.443635475178810342493276740273105f32);
+    assert_approx_eq!((-2.0f32).asinh(), -1.443635475178810342493276740273105f32);
+    // regression test for the catastrophic cancellation fixed in 72486
+    assert_approx_eq!((-3000.0f32).asinh(), -8.699514775987968673236893537700647f32);
+
+    // test for low accuracy from issue 104548
+    assert_approx_eq!(60.0f32, 60.0f32.sinh().asinh());
+    // mul needed for approximate comparison to be meaningful
+    assert_approx_eq!(1.0f32, 1e-15f32.sinh().asinh() * 1e15f32);
+}
+
+#[test]
+fn test_acosh() {
+    assert_eq!(1.0f32.acosh(), 0.0f32);
+    assert!(0.999f32.acosh().is_nan());
+
+    let inf: f32 = f32::INFINITY;
+    let neg_inf: f32 = f32::NEG_INFINITY;
+    let nan: f32 = f32::NAN;
+    assert_eq!(inf.acosh(), inf);
+    assert!(neg_inf.acosh().is_nan());
+    assert!(nan.acosh().is_nan());
+    assert_approx_eq!(2.0f32.acosh(), 1.31695789692481670862504634730796844f32);
+    assert_approx_eq!(3.0f32.acosh(), 1.76274717403908605046521864995958461f32);
+
+    // test for low accuracy from issue 104548
+    assert_approx_eq!(60.0f32, 60.0f32.cosh().acosh());
+}
+
+#[test]
+fn test_atanh() {
+    assert_eq!(0.0f32.atanh(), 0.0f32);
+    assert_eq!((-0.0f32).atanh(), -0.0f32);
+
+    let inf32: f32 = f32::INFINITY;
+    let neg_inf32: f32 = f32::NEG_INFINITY;
+    assert_eq!(1.0f32.atanh(), inf32);
+    assert_eq!((-1.0f32).atanh(), neg_inf32);
+
+    assert!(2f64.atanh().atanh().is_nan());
+    assert!((-2f64).atanh().atanh().is_nan());
+
+    let inf64: f32 = f32::INFINITY;
+    let neg_inf64: f32 = f32::NEG_INFINITY;
+    let nan32: f32 = f32::NAN;
+    assert!(inf64.atanh().is_nan());
+    assert!(neg_inf64.atanh().is_nan());
+    assert!(nan32.atanh().is_nan());
+
+    assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32);
+    assert_approx_eq!((-0.5f32).atanh(), -0.54930614433405484569762261846126285f32);
+}
+
+#[test]
+fn test_gamma() {
+    // precision can differ between platforms
+    assert_approx_eq!(1.0f32.gamma(), 1.0f32);
+    assert_approx_eq!(2.0f32.gamma(), 1.0f32);
+    assert_approx_eq!(3.0f32.gamma(), 2.0f32);
+    assert_approx_eq!(4.0f32.gamma(), 6.0f32);
+    assert_approx_eq!(5.0f32.gamma(), 24.0f32);
+    assert_approx_eq!(0.5f32.gamma(), consts::PI.sqrt());
+    assert_approx_eq!((-0.5f32).gamma(), -2.0 * consts::PI.sqrt());
+    assert_eq!(0.0f32.gamma(), f32::INFINITY);
+    assert_eq!((-0.0f32).gamma(), f32::NEG_INFINITY);
+    assert!((-1.0f32).gamma().is_nan());
+    assert!((-2.0f32).gamma().is_nan());
+    assert!(f32::NAN.gamma().is_nan());
+    assert!(f32::NEG_INFINITY.gamma().is_nan());
+    assert_eq!(f32::INFINITY.gamma(), f32::INFINITY);
+    assert_eq!(171.71f32.gamma(), f32::INFINITY);
+}
+
+#[test]
+fn test_ln_gamma() {
+    assert_approx_eq!(1.0f32.ln_gamma().0, 0.0f32);
+    assert_eq!(1.0f32.ln_gamma().1, 1);
+    assert_approx_eq!(2.0f32.ln_gamma().0, 0.0f32);
+    assert_eq!(2.0f32.ln_gamma().1, 1);
+    assert_approx_eq!(3.0f32.ln_gamma().0, 2.0f32.ln());
+    assert_eq!(3.0f32.ln_gamma().1, 1);
+    assert_approx_eq!((-0.5f32).ln_gamma().0, (2.0 * consts::PI.sqrt()).ln());
+    assert_eq!((-0.5f32).ln_gamma().1, -1);
+}
+
+#[test]
+fn test_real_consts() {
+    let pi: f32 = consts::PI;
+    let frac_pi_2: f32 = consts::FRAC_PI_2;
+    let frac_pi_3: f32 = consts::FRAC_PI_3;
+    let frac_pi_4: f32 = consts::FRAC_PI_4;
+    let frac_pi_6: f32 = consts::FRAC_PI_6;
+    let frac_pi_8: f32 = consts::FRAC_PI_8;
+    let frac_1_pi: f32 = consts::FRAC_1_PI;
+    let frac_2_pi: f32 = consts::FRAC_2_PI;
+    let frac_2_sqrtpi: f32 = consts::FRAC_2_SQRT_PI;
+    let sqrt2: f32 = consts::SQRT_2;
+    let frac_1_sqrt2: f32 = consts::FRAC_1_SQRT_2;
+    let e: f32 = consts::E;
+    let log2_e: f32 = consts::LOG2_E;
+    let log10_e: f32 = consts::LOG10_E;
+    let ln_2: f32 = consts::LN_2;
+    let ln_10: f32 = consts::LN_10;
+
+    assert_approx_eq!(frac_pi_2, pi / 2f32);
+    assert_approx_eq!(frac_pi_3, pi / 3f32);
+    assert_approx_eq!(frac_pi_4, pi / 4f32);
+    assert_approx_eq!(frac_pi_6, pi / 6f32);
+    assert_approx_eq!(frac_pi_8, pi / 8f32);
+    assert_approx_eq!(frac_1_pi, 1f32 / pi);
+    assert_approx_eq!(frac_2_pi, 2f32 / pi);
+    assert_approx_eq!(frac_2_sqrtpi, 2f32 / pi.sqrt());
+    assert_approx_eq!(sqrt2, 2f32.sqrt());
+    assert_approx_eq!(frac_1_sqrt2, 1f32 / 2f32.sqrt());
+    assert_approx_eq!(log2_e, e.log2());
+    assert_approx_eq!(log10_e, e.log10());
+    assert_approx_eq!(ln_2, 2f32.ln());
+    assert_approx_eq!(ln_10, 10f32.ln());
+}
diff --git a/library/std/tests/floats/f64.rs b/library/std/tests/floats/f64.rs
new file mode 100644
index 00000000000..2d8dd1cf091
--- /dev/null
+++ b/library/std/tests/floats/f64.rs
@@ -0,0 +1,249 @@
+use std::f64::consts;
+
+#[allow(unused_macros)]
+macro_rules! assert_f64_biteq {
+    ($left : expr, $right : expr) => {
+        let l: &f64 = &$left;
+        let r: &f64 = &$right;
+        let lb = l.to_bits();
+        let rb = r.to_bits();
+        assert_eq!(lb, rb, "float {l} ({lb:#018x}) is not bitequal to {r} ({rb:#018x})");
+    };
+}
+
+#[test]
+fn test_powf() {
+    let nan: f64 = f64::NAN;
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    assert_eq!(1.0f64.powf(1.0), 1.0);
+    assert_approx_eq!(3.4f64.powf(4.5), 246.408183);
+    assert_approx_eq!(2.7f64.powf(-3.2), 0.041652);
+    assert_approx_eq!((-3.1f64).powf(2.0), 9.61);
+    assert_approx_eq!(5.9f64.powf(-2.0), 0.028727);
+    assert_eq!(8.3f64.powf(0.0), 1.0);
+    assert!(nan.powf(2.0).is_nan());
+    assert_eq!(inf.powf(2.0), inf);
+    assert_eq!(neg_inf.powf(3.0), neg_inf);
+}
+
+#[test]
+fn test_exp() {
+    assert_eq!(1.0, 0.0f64.exp());
+    assert_approx_eq!(2.718282, 1.0f64.exp());
+    assert_approx_eq!(148.413159, 5.0f64.exp());
+
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    let nan: f64 = f64::NAN;
+    assert_eq!(inf, inf.exp());
+    assert_eq!(0.0, neg_inf.exp());
+    assert!(nan.exp().is_nan());
+}
+
+#[test]
+fn test_exp2() {
+    assert_eq!(32.0, 5.0f64.exp2());
+    assert_eq!(1.0, 0.0f64.exp2());
+
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    let nan: f64 = f64::NAN;
+    assert_eq!(inf, inf.exp2());
+    assert_eq!(0.0, neg_inf.exp2());
+    assert!(nan.exp2().is_nan());
+}
+
+#[test]
+fn test_ln() {
+    let nan: f64 = f64::NAN;
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    assert_approx_eq!(1.0f64.exp().ln(), 1.0);
+    assert!(nan.ln().is_nan());
+    assert_eq!(inf.ln(), inf);
+    assert!(neg_inf.ln().is_nan());
+    assert!((-2.3f64).ln().is_nan());
+    assert_eq!((-0.0f64).ln(), neg_inf);
+    assert_eq!(0.0f64.ln(), neg_inf);
+    assert_approx_eq!(4.0f64.ln(), 1.386294);
+}
+
+#[test]
+fn test_log() {
+    let nan: f64 = f64::NAN;
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    assert_eq!(10.0f64.log(10.0), 1.0);
+    assert_approx_eq!(2.3f64.log(3.5), 0.664858);
+    assert_eq!(1.0f64.exp().log(1.0f64.exp()), 1.0);
+    assert!(1.0f64.log(1.0).is_nan());
+    assert!(1.0f64.log(-13.9).is_nan());
+    assert!(nan.log(2.3).is_nan());
+    assert_eq!(inf.log(10.0), inf);
+    assert!(neg_inf.log(8.8).is_nan());
+    assert!((-2.3f64).log(0.1).is_nan());
+    assert_eq!((-0.0f64).log(2.0), neg_inf);
+    assert_eq!(0.0f64.log(7.0), neg_inf);
+}
+
+#[test]
+fn test_log2() {
+    let nan: f64 = f64::NAN;
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    assert_approx_eq!(10.0f64.log2(), 3.321928);
+    assert_approx_eq!(2.3f64.log2(), 1.201634);
+    assert_approx_eq!(1.0f64.exp().log2(), 1.442695);
+    assert!(nan.log2().is_nan());
+    assert_eq!(inf.log2(), inf);
+    assert!(neg_inf.log2().is_nan());
+    assert!((-2.3f64).log2().is_nan());
+    assert_eq!((-0.0f64).log2(), neg_inf);
+    assert_eq!(0.0f64.log2(), neg_inf);
+}
+
+#[test]
+fn test_log10() {
+    let nan: f64 = f64::NAN;
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    assert_eq!(10.0f64.log10(), 1.0);
+    assert_approx_eq!(2.3f64.log10(), 0.361728);
+    assert_approx_eq!(1.0f64.exp().log10(), 0.434294);
+    assert_eq!(1.0f64.log10(), 0.0);
+    assert!(nan.log10().is_nan());
+    assert_eq!(inf.log10(), inf);
+    assert!(neg_inf.log10().is_nan());
+    assert!((-2.3f64).log10().is_nan());
+    assert_eq!((-0.0f64).log10(), neg_inf);
+    assert_eq!(0.0f64.log10(), neg_inf);
+}
+
+#[test]
+fn test_asinh() {
+    assert_eq!(0.0f64.asinh(), 0.0f64);
+    assert_eq!((-0.0f64).asinh(), -0.0f64);
+
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    let nan: f64 = f64::NAN;
+    assert_eq!(inf.asinh(), inf);
+    assert_eq!(neg_inf.asinh(), neg_inf);
+    assert!(nan.asinh().is_nan());
+    assert!((-0.0f64).asinh().is_sign_negative());
+    // issue 63271
+    assert_approx_eq!(2.0f64.asinh(), 1.443635475178810342493276740273105f64);
+    assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64);
+    // regression test for the catastrophic cancellation fixed in 72486
+    assert_approx_eq!((-67452098.07139316f64).asinh(), -18.72007542627454439398548429400083);
+
+    // test for low accuracy from issue 104548
+    assert_approx_eq!(60.0f64, 60.0f64.sinh().asinh());
+    // mul needed for approximate comparison to be meaningful
+    assert_approx_eq!(1.0f64, 1e-15f64.sinh().asinh() * 1e15f64);
+}
+
+#[test]
+fn test_acosh() {
+    assert_eq!(1.0f64.acosh(), 0.0f64);
+    assert!(0.999f64.acosh().is_nan());
+
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    let nan: f64 = f64::NAN;
+    assert_eq!(inf.acosh(), inf);
+    assert!(neg_inf.acosh().is_nan());
+    assert!(nan.acosh().is_nan());
+    assert_approx_eq!(2.0f64.acosh(), 1.31695789692481670862504634730796844f64);
+    assert_approx_eq!(3.0f64.acosh(), 1.76274717403908605046521864995958461f64);
+
+    // test for low accuracy from issue 104548
+    assert_approx_eq!(60.0f64, 60.0f64.cosh().acosh());
+}
+
+#[test]
+fn test_atanh() {
+    assert_eq!(0.0f64.atanh(), 0.0f64);
+    assert_eq!((-0.0f64).atanh(), -0.0f64);
+
+    let inf: f64 = f64::INFINITY;
+    let neg_inf: f64 = f64::NEG_INFINITY;
+    let nan: f64 = f64::NAN;
+    assert_eq!(1.0f64.atanh(), inf);
+    assert_eq!((-1.0f64).atanh(), neg_inf);
+    assert!(2f64.atanh().atanh().is_nan());
+    assert!((-2f64).atanh().atanh().is_nan());
+    assert!(inf.atanh().is_nan());
+    assert!(neg_inf.atanh().is_nan());
+    assert!(nan.atanh().is_nan());
+    assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64);
+    assert_approx_eq!((-0.5f64).atanh(), -0.54930614433405484569762261846126285f64);
+}
+
+#[test]
+fn test_gamma() {
+    // precision can differ between platforms
+    assert_approx_eq!(1.0f64.gamma(), 1.0f64);
+    assert_approx_eq!(2.0f64.gamma(), 1.0f64);
+    assert_approx_eq!(3.0f64.gamma(), 2.0f64);
+    assert_approx_eq!(4.0f64.gamma(), 6.0f64);
+    assert_approx_eq!(5.0f64.gamma(), 24.0f64);
+    assert_approx_eq!(0.5f64.gamma(), consts::PI.sqrt());
+    assert_approx_eq!((-0.5f64).gamma(), -2.0 * consts::PI.sqrt());
+    assert_eq!(0.0f64.gamma(), f64::INFINITY);
+    assert_eq!((-0.0f64).gamma(), f64::NEG_INFINITY);
+    assert!((-1.0f64).gamma().is_nan());
+    assert!((-2.0f64).gamma().is_nan());
+    assert!(f64::NAN.gamma().is_nan());
+    assert!(f64::NEG_INFINITY.gamma().is_nan());
+    assert_eq!(f64::INFINITY.gamma(), f64::INFINITY);
+    assert_eq!(171.71f64.gamma(), f64::INFINITY);
+}
+
+#[test]
+fn test_ln_gamma() {
+    assert_approx_eq!(1.0f64.ln_gamma().0, 0.0f64);
+    assert_eq!(1.0f64.ln_gamma().1, 1);
+    assert_approx_eq!(2.0f64.ln_gamma().0, 0.0f64);
+    assert_eq!(2.0f64.ln_gamma().1, 1);
+    assert_approx_eq!(3.0f64.ln_gamma().0, 2.0f64.ln());
+    assert_eq!(3.0f64.ln_gamma().1, 1);
+    assert_approx_eq!((-0.5f64).ln_gamma().0, (2.0 * consts::PI.sqrt()).ln());
+    assert_eq!((-0.5f64).ln_gamma().1, -1);
+}
+
+#[test]
+fn test_real_consts() {
+    let pi: f64 = consts::PI;
+    let frac_pi_2: f64 = consts::FRAC_PI_2;
+    let frac_pi_3: f64 = consts::FRAC_PI_3;
+    let frac_pi_4: f64 = consts::FRAC_PI_4;
+    let frac_pi_6: f64 = consts::FRAC_PI_6;
+    let frac_pi_8: f64 = consts::FRAC_PI_8;
+    let frac_1_pi: f64 = consts::FRAC_1_PI;
+    let frac_2_pi: f64 = consts::FRAC_2_PI;
+    let frac_2_sqrtpi: f64 = consts::FRAC_2_SQRT_PI;
+    let sqrt2: f64 = consts::SQRT_2;
+    let frac_1_sqrt2: f64 = consts::FRAC_1_SQRT_2;
+    let e: f64 = consts::E;
+    let log2_e: f64 = consts::LOG2_E;
+    let log10_e: f64 = consts::LOG10_E;
+    let ln_2: f64 = consts::LN_2;
+    let ln_10: f64 = consts::LN_10;
+
+    assert_approx_eq!(frac_pi_2, pi / 2f64);
+    assert_approx_eq!(frac_pi_3, pi / 3f64);
+    assert_approx_eq!(frac_pi_4, pi / 4f64);
+    assert_approx_eq!(frac_pi_6, pi / 6f64);
+    assert_approx_eq!(frac_pi_8, pi / 8f64);
+    assert_approx_eq!(frac_1_pi, 1f64 / pi);
+    assert_approx_eq!(frac_2_pi, 2f64 / pi);
+    assert_approx_eq!(frac_2_sqrtpi, 2f64 / pi.sqrt());
+    assert_approx_eq!(sqrt2, 2f64.sqrt());
+    assert_approx_eq!(frac_1_sqrt2, 1f64 / 2f64.sqrt());
+    assert_approx_eq!(log2_e, e.log2());
+    assert_approx_eq!(log10_e, e.log10());
+    assert_approx_eq!(ln_2, 2f64.ln());
+    assert_approx_eq!(ln_10, 10f64.ln());
+}
diff --git a/library/std/tests/floats/lib.rs b/library/std/tests/floats/lib.rs
new file mode 100644
index 00000000000..8bb8eb4bfc1
--- /dev/null
+++ b/library/std/tests/floats/lib.rs
@@ -0,0 +1,43 @@
+#![feature(f16, f128, float_gamma, float_minimum_maximum, cfg_target_has_reliable_f16_f128)]
+#![expect(internal_features)] // for reliable_f16_f128
+
+use std::fmt;
+use std::ops::{Add, Div, Mul, Rem, Sub};
+
+/// Verify that floats are within a tolerance of each other, 1.0e-6 by default.
+macro_rules! assert_approx_eq {
+    ($a:expr, $b:expr) => {{ assert_approx_eq!($a, $b, 1.0e-6) }};
+    ($a:expr, $b:expr, $lim:expr) => {{
+        let (a, b) = (&$a, &$b);
+        let diff = (*a - *b).abs();
+        assert!(
+            diff <= $lim,
+            "{a:?} is not approximately equal to {b:?} (threshold {lim:?}, difference {diff:?})",
+            lim = $lim
+        );
+    }};
+}
+
+/// Helper function for testing numeric operations
+pub fn test_num<T>(ten: T, two: T)
+where
+    T: PartialEq
+        + Add<Output = T>
+        + Sub<Output = T>
+        + Mul<Output = T>
+        + Div<Output = T>
+        + Rem<Output = T>
+        + fmt::Debug
+        + Copy,
+{
+    assert_eq!(ten.add(two), ten + two);
+    assert_eq!(ten.sub(two), ten - two);
+    assert_eq!(ten.mul(two), ten * two);
+    assert_eq!(ten.div(two), ten / two);
+    assert_eq!(ten.rem(two), ten % two);
+}
+
+mod f128;
+mod f16;
+mod f32;
+mod f64;