dedup powi float test

This commit is contained in:
Karol Zwolak 2025-08-15 10:10:54 +02:00
parent 6ebd009d47
commit e10e6d78ac
5 changed files with 28 additions and 66 deletions

View file

@ -52,22 +52,6 @@ fn test_max_recip() {
);
}
#[test]
#[cfg(not(miri))]
#[cfg(target_has_reliable_f128_math)]
fn test_powi() {
let nan: f128 = f128::NAN;
let inf: f128 = f128::INFINITY;
let neg_inf: f128 = f128::NEG_INFINITY;
assert_biteq!(1.0f128.powi(1), 1.0);
assert_approx_eq!((-3.1f128).powi(2), 9.6100000000000005506706202140776519387, TOL);
assert_approx_eq!(5.9f128.powi(-2), 0.028727377190462507313100483690639638451, TOL);
assert_biteq!(8.3f128.powi(0), 1.0);
assert!(nan.powi(2).is_nan());
assert_biteq!(inf.powi(3), inf);
assert_biteq!(neg_inf.powi(2), inf);
}
#[test]
fn test_to_degrees() {
let pi: f128 = consts::PI;

View file

@ -54,22 +54,6 @@ fn test_max_recip() {
assert_approx_eq!(f16::MAX.recip(), 1.526624e-5f16, 1e-4);
}
#[test]
#[cfg(not(miri))]
#[cfg(target_has_reliable_f16_math)]
fn test_powi() {
let nan: f16 = f16::NAN;
let inf: f16 = f16::INFINITY;
let neg_inf: f16 = f16::NEG_INFINITY;
assert_biteq!(1.0f16.powi(1), 1.0);
assert_approx_eq!((-3.1f16).powi(2), 9.61, TOL_0);
assert_approx_eq!(5.9f16.powi(-2), 0.028727, TOL_N2);
assert_biteq!(8.3f16.powi(0), 1.0);
assert!(nan.powi(2).is_nan());
assert_biteq!(inf.powi(3), inf);
assert_biteq!(neg_inf.powi(2), inf);
}
#[test]
fn test_to_degrees() {
let pi: f16 = consts::PI;

View file

@ -9,11 +9,6 @@ const NAN_MASK1: u32 = 0x002a_aaaa;
/// Second pattern over the mantissa
const NAN_MASK2: u32 = 0x0055_5555;
/// Miri adds some extra errors to float functions; make sure the tests still pass.
/// These values are purely used as a canary to test against and are thus not a stable guarantee Rust provides.
/// They serve as a way to get an idea of the real precision of floating point operations on different platforms.
const APPROX_DELTA: f32 = if cfg!(miri) { 1e-4 } else { 1e-6 };
// FIXME(#140515): mingw has an incorrect fma https://sourceforge.net/p/mingw-w64/bugs/848/
#[cfg_attr(all(target_os = "windows", target_env = "gnu", not(target_abi = "llvm")), ignore)]
#[test]
@ -32,20 +27,6 @@ fn test_mul_add() {
assert_biteq!(f32::math::mul_add(-3.2f32, 2.4, neg_inf), neg_inf);
}
#[test]
fn test_powi() {
let nan: f32 = f32::NAN;
let inf: f32 = f32::INFINITY;
let neg_inf: f32 = f32::NEG_INFINITY;
assert_approx_eq!(1.0f32.powi(1), 1.0);
assert_approx_eq!((-3.1f32).powi(2), 9.61, APPROX_DELTA);
assert_approx_eq!(5.9f32.powi(-2), 0.028727);
assert_biteq!(8.3f32.powi(0), 1.0);
assert!(nan.powi(2).is_nan());
assert_biteq!(inf.powi(3), inf);
assert_biteq!(neg_inf.powi(2), inf);
}
#[test]
fn test_to_degrees() {
let pi: f32 = consts::PI;

View file

@ -27,20 +27,6 @@ fn test_mul_add() {
assert_biteq!((-3.2f64).mul_add(2.4, neg_inf), neg_inf);
}
#[test]
fn test_powi() {
let nan: f64 = f64::NAN;
let inf: f64 = f64::INFINITY;
let neg_inf: f64 = f64::NEG_INFINITY;
assert_approx_eq!(1.0f64.powi(1), 1.0);
assert_approx_eq!((-3.1f64).powi(2), 9.61);
assert_approx_eq!(5.9f64.powi(-2), 0.028727);
assert_biteq!(8.3f64.powi(0), 1.0);
assert!(nan.powi(2).is_nan());
assert_biteq!(inf.powi(3), inf);
assert_biteq!(neg_inf.powi(2), inf);
}
#[test]
fn test_to_degrees() {
let pi: f64 = consts::PI;

View file

@ -1,11 +1,13 @@
use std::num::FpCategory as Fp;
use std::ops::{Add, Div, Mul, Rem, Sub};
trait TestableFloat {
trait TestableFloat: Sized {
/// Unsigned int with the same size, for converting to/from bits.
type Int;
/// Set the default tolerance for float comparison based on the type.
const APPROX: Self;
/// Allow looser tolerance for f32 on miri
const POWI_APPROX: Self = Self::APPROX;
const ZERO: Self;
const ONE: Self;
const MIN_POSITIVE_NORMAL: Self;
@ -39,6 +41,10 @@ impl TestableFloat for f16 {
impl TestableFloat for f32 {
type Int = u32;
const APPROX: Self = 1e-6;
/// Miri adds some extra errors to float functions; make sure the tests still pass.
/// These values are purely used as a canary to test against and are thus not a stable guarantee Rust provides.
/// They serve as a way to get an idea of the real precision of floating point operations on different platforms.
const POWI_APPROX: Self = if cfg!(miri) { 1e-4 } else { Self::APPROX };
const ZERO: Self = 0.0;
const ONE: Self = 1.0;
const MIN_POSITIVE_NORMAL: Self = Self::MIN_POSITIVE;
@ -1360,3 +1366,24 @@ float_test! {
assert_biteq!(neg_inf.recip(), -0.0);
}
}
float_test! {
name: powi,
attrs: {
const: #[cfg(false)],
f16: #[cfg(all(not(miri), target_has_reliable_f16_math))],
f128: #[cfg(all(not(miri), target_has_reliable_f128_math))],
},
test<Float> {
let nan: Float = Float::NAN;
let inf: Float = Float::INFINITY;
let neg_inf: Float = Float::NEG_INFINITY;
assert_approx_eq!(Float::ONE.powi(1), Float::ONE);
assert_approx_eq!((-3.1 as Float).powi(2), 9.6100000000000005506706202140776519387, Float::POWI_APPROX);
assert_approx_eq!((5.9 as Float).powi(-2), 0.028727377190462507313100483690639638451);
assert_biteq!((8.3 as Float).powi(0), Float::ONE);
assert!(nan.powi(2).is_nan());
assert_biteq!(inf.powi(3), inf);
assert_biteq!(neg_inf.powi(2), inf);
}
}