Consolidate is_normal tests

This commit is contained in:
Roger Curley 2025-07-10 10:20:45 -04:00
parent 7dd2811b2a
commit d2c1900086
5 changed files with 51 additions and 82 deletions

View file

@ -40,23 +40,6 @@ const NAN_MASK2: u128 = 0x00005555555555555555555555555555;
// FIXME(f16_f128,miri): many of these have to be disabled since miri does not yet support
// the intrinsics.
#[test]
fn test_is_normal() {
let nan: f128 = f128::NAN;
let inf: f128 = f128::INFINITY;
let neg_inf: f128 = f128::NEG_INFINITY;
let zero: f128 = 0.0f128;
let neg_zero: f128 = -0.0;
assert!(!nan.is_normal());
assert!(!inf.is_normal());
assert!(!neg_inf.is_normal());
assert!(!zero.is_normal());
assert!(!neg_zero.is_normal());
assert!(1f128.is_normal());
assert!(1e-4931f128.is_normal());
assert!(!1e-4932f128.is_normal());
}
#[test]
fn test_classify() {
let nan: f128 = f128::NAN;

View file

@ -46,23 +46,6 @@ const NAN_MASK2: u16 = 0x0155;
// FIXME(f16_f128,miri): many of these have to be disabled since miri does not yet support
// the intrinsics.
#[test]
fn test_is_normal() {
let nan: f16 = f16::NAN;
let inf: f16 = f16::INFINITY;
let neg_inf: f16 = f16::NEG_INFINITY;
let zero: f16 = 0.0f16;
let neg_zero: f16 = -0.0;
assert!(!nan.is_normal());
assert!(!inf.is_normal());
assert!(!neg_inf.is_normal());
assert!(!zero.is_normal());
assert!(!neg_zero.is_normal());
assert!(1f16.is_normal());
assert!(1e-4f16.is_normal());
assert!(!1e-5f16.is_normal());
}
#[test]
fn test_classify() {
let nan: f16 = f16::NAN;

View file

@ -30,23 +30,6 @@ const NAN_MASK2: u32 = 0x0055_5555;
/// 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 };
#[test]
fn test_is_normal() {
let nan: f32 = f32::NAN;
let inf: f32 = f32::INFINITY;
let neg_inf: f32 = f32::NEG_INFINITY;
let zero: f32 = 0.0f32;
let neg_zero: f32 = -0.0;
assert!(!nan.is_normal());
assert!(!inf.is_normal());
assert!(!neg_inf.is_normal());
assert!(!zero.is_normal());
assert!(!neg_zero.is_normal());
assert!(1f32.is_normal());
assert!(1e-37f32.is_normal());
assert!(!1e-38f32.is_normal());
}
#[test]
fn test_classify() {
let nan: f32 = f32::NAN;

View file

@ -25,23 +25,6 @@ const NAN_MASK1: u64 = 0x000a_aaaa_aaaa_aaaa;
/// Second pattern over the mantissa
const NAN_MASK2: u64 = 0x0005_5555_5555_5555;
#[test]
fn test_is_normal() {
let nan: f64 = f64::NAN;
let inf: f64 = f64::INFINITY;
let neg_inf: f64 = f64::NEG_INFINITY;
let zero: f64 = 0.0f64;
let neg_zero: f64 = -0.0;
assert!(!nan.is_normal());
assert!(!inf.is_normal());
assert!(!neg_inf.is_normal());
assert!(!zero.is_normal());
assert!(!neg_zero.is_normal());
assert!(1f64.is_normal());
assert!(1e-307f64.is_normal());
assert!(!1e-308f64.is_normal());
}
#[test]
fn test_classify() {
let nan: f64 = f64::NAN;

View file

@ -1,27 +1,40 @@
use std::num::FpCategory as Fp;
use std::ops::{Add, Div, Mul, Rem, Sub};
/// Set the default tolerance for float comparison based on the type.
trait Approx {
const LIM: Self;
trait TestableFloat {
/// Set the default tolerance for float comparison based on the type.
const APPROX: Self;
const MIN_POSITIVE_NORMAL: Self;
const MAX_SUBNORMAL: Self;
}
impl Approx for f16 {
const LIM: Self = 1e-3;
impl TestableFloat for f16 {
const APPROX: Self = 1e-3;
const MIN_POSITIVE_NORMAL: Self = Self::MIN_POSITIVE;
const MAX_SUBNORMAL: Self = Self::MIN_POSITIVE.next_down();
}
impl Approx for f32 {
const LIM: Self = 1e-6;
impl TestableFloat for f32 {
const APPROX: Self = 1e-6;
const MIN_POSITIVE_NORMAL: Self = Self::MIN_POSITIVE;
const MAX_SUBNORMAL: Self = Self::MIN_POSITIVE.next_down();
}
impl Approx for f64 {
const LIM: Self = 1e-6;
impl TestableFloat for f64 {
const APPROX: Self = 1e-6;
const MIN_POSITIVE_NORMAL: Self = Self::MIN_POSITIVE;
const MAX_SUBNORMAL: Self = Self::MIN_POSITIVE.next_down();
}
impl Approx for f128 {
const LIM: Self = 1e-9;
impl TestableFloat for f128 {
const APPROX: Self = 1e-9;
const MIN_POSITIVE_NORMAL: Self = Self::MIN_POSITIVE;
const MAX_SUBNORMAL: Self = Self::MIN_POSITIVE.next_down();
}
/// Determine the tolerance for values of the argument type.
const fn lim_for_ty<T: Approx + Copy>(_x: T) -> T {
T::LIM
const fn lim_for_ty<T: TestableFloat + Copy>(_x: T) -> T {
T::APPROX
}
// We have runtime ("rt") and const versions of these macros.
@ -186,7 +199,7 @@ macro_rules! float_test {
$( $( #[$const_meta] )+ )?
mod const_ {
#[allow(unused)]
use super::Approx;
use super::TestableFloat;
#[allow(unused)]
use std::num::FpCategory as Fp;
#[allow(unused)]
@ -446,6 +459,30 @@ float_test! {
}
}
float_test! {
name: is_normal,
attrs: {
f16: #[cfg(any(miri, target_has_reliable_f16))],
f128: #[cfg(any(miri, target_has_reliable_f128))],
},
test<Float> {
let nan: Float = Float::NAN;
let inf: Float = Float::INFINITY;
let neg_inf: Float = Float::NEG_INFINITY;
let zero: Float = 0.0;
let neg_zero: Float = -0.0;
let one : Float = 1.0;
assert!(!nan.is_normal());
assert!(!inf.is_normal());
assert!(!neg_inf.is_normal());
assert!(!zero.is_normal());
assert!(!neg_zero.is_normal());
assert!(one.is_normal());
assert!(Float::MIN_POSITIVE_NORMAL.is_normal());
assert!(!Float::MAX_SUBNORMAL.is_normal());
}
}
float_test! {
name: min,
attrs: {