From 19a57e73620cdc0314fe3757e233757d27c6c274 Mon Sep 17 00:00:00 2001 From: Mathilda Date: Wed, 26 Jun 2024 20:17:05 -0400 Subject: [PATCH] Add unit tests for `integer_decode_f32` and `integer_decode_f64` --- src/float.rs | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/src/float.rs b/src/float.rs index d0d21a5..5f841ba 100644 --- a/src/float.rs +++ b/src/float.rs @@ -2397,6 +2397,94 @@ mod tests { check::(1e-12); } + #[test] + #[cfg(any(feature = "std", feature = "libm"))] + fn integer_decode_f32() { + use crate::Float; + use core::f32; + use std::format; + + fn check(x: f32, x_mantissa: u64, x_exponent: i16, x_sign: i8) { + let (mantissa, exponent, sign) = Float::integer_decode(x); + assert!( + (x_mantissa, x_exponent, x_sign) == (mantissa, exponent, sign), + "{}\n\t{}\n\t{}", + format!("while testing return value of Float::integer_decode({})", x), + format!("expected: ({:#x} {} {})", x_mantissa, x_exponent, x_sign), + format!(" found: ({:#x} {} {})", mantissa, exponent, sign), + ); + + let sign_f = sign as f32; + let mantissa_f = mantissa as f32; + let exponent_f = exponent as f32; + + let abs_difference = (sign_f * mantissa_f * 2_f32.powf(exponent_f) - x).abs(); + + assert!(abs_difference < 1e-10, "absolute difference {} must be less than 1e-10", abs_difference); + } + + for sign in [1, -1] { + let sign_f = sign as f32; + check(sign_f * 0.0_f32, 0x000000, -150, sign); + check(sign_f * f32::MIN_POSITIVE, 0x800000, -149, sign); + check(sign_f * 0.25_f32, 0x800000, -25, sign); + check(sign_f * 0.5_f32, 0x800000, -24, sign); + check(sign_f * 1_f32, 0x800000, -23, sign); + check(sign_f * 1.5_f32, 0xc00000, -23, sign); + check(sign_f * 2_f32, 0x800000, -22, sign); + check(sign_f * 2.5_f32, 0xa00000, -22, sign); + check(sign_f * 3_f32, 0xc00000, -22, sign); + check(sign_f * 4_f32, 0x800000, -21, sign); + check(sign_f * 5_f32, 0xa00000, -21, sign); + check(sign_f * 42_f32, 0xa80000, -18, sign); + check(sign_f * f32::MAX, 0xffffff, 104, sign); + } + } + + #[test] + #[cfg(any(feature = "std", feature = "libm"))] + fn integer_decode_f64() { + use crate::Float; + use core::f64; + use std::format; + + fn check(x: f64, x_mantissa: u64, x_exponent: i16, x_sign: i8) { + let (mantissa, exponent, sign) = Float::integer_decode(x); + assert!( + (x_mantissa, x_exponent, x_sign) == (mantissa, exponent, sign), + "{}\n\t{}\n\t{}", + format!("while testing return value of Float::integer_decode({})", x), + format!("expected: ({:#x} {} {})", x_mantissa, x_exponent, x_sign), + format!(" found: ({:#x} {} {})", mantissa, exponent, sign), + ); + + let sign_f = sign as f64; + let mantissa_f = mantissa as f64; + let exponent_f = exponent as f64; + + let abs_difference = (sign_f * mantissa_f * 2_f64.powf(exponent_f) - x).abs(); + + assert!(abs_difference < 1e-10, "absolute difference {} must be less than 1e-10", abs_difference); + } + + for sign in [1, -1] { + let sign_f = sign as f64; + check(sign_f * 0.0_f64, 0x00000000000000, -1075, sign); + check(sign_f * f64::MIN_POSITIVE, 0x10000000000000, -1074, sign); + check(sign_f * 0.25_f64, 0x10000000000000, -54, sign); + check(sign_f * 0.5_f64, 0x10000000000000, -53, sign); + check(sign_f * 1_f64, 0x10000000000000, -52, sign); + check(sign_f * 1.5_f64, 0x18000000000000, -52, sign); + check(sign_f * 2_f64, 0x10000000000000, -51, sign); + check(sign_f * 2.5_f64, 0x14000000000000, -51, sign); + check(sign_f * 3_f64, 0x18000000000000, -51, sign); + check(sign_f * 4_f64, 0x10000000000000, -50, sign); + check(sign_f * 5_f64, 0x14000000000000, -50, sign); + check(sign_f * 42_f64, 0x15000000000000, -47, sign); + check(sign_f * f64::MAX, 0x1fffffffffffff, 971, sign); + } + } + #[test] #[cfg(any(feature = "std", feature = "libm"))] fn copysign() {