Added more tests and documentation for float ulps functions in rmath.

This commit is contained in:
Nathan Vegdahl 2023-08-03 23:20:29 +02:00
parent 76c56e16f9
commit f9acc8096c

View File

@ -1,6 +1,13 @@
const TOP_BIT: u32 = 1 << 31;
/// Compute how different two floats are in ulps.
///
/// Notes:
/// - Treats 0.0 and -0.0 as zero ulps apart, and extends the
/// implications of that to the rest of the numbers. E.g. the numbers
/// just before and after 0.0/-0.0 are only two ulps apart, not three.
/// - Infinity is one ulp past float max, and converse for -infinity.
/// - This doesn't handle NaNs in any really useful way.
#[inline(always)]
pub fn ulp_diff(a: f32, b: f32) -> u32 {
let a = a.to_bits();
@ -34,12 +41,20 @@ mod tests {
assert_eq!(ulp_diff(0.0, 0.0), 0);
assert_eq!(ulp_diff(0.0, -0.0), 0);
assert_eq!(ulp_diff(1.0, 2.0), 1 << 23);
assert_eq!(ulp_diff(0.0, f32::from_bits(0.0f32.to_bits() + 1)), 1);
assert_eq!(ulp_diff(-0.0, f32::from_bits(0.0f32.to_bits() + 1)), 1);
assert_eq!(ulp_diff(2.0, 4.0), 1 << 23);
assert_eq!(ulp_diff(-1.0, -2.0), 1 << 23);
assert_eq!(ulp_diff(-2.0, -4.0), 1 << 23);
assert_eq!(ulp_diff(-1.0, 1.0), 0x7f000000);
assert_eq!(ulp_diff(0.0, 1.0), 0x3f800000);
assert_eq!(ulp_diff(-0.0, 1.0), 0x3f800000);
assert_eq!(ulp_diff(0.0, -1.0), 0x3f800000);
assert_eq!(ulp_diff(-0.0, -1.0), 0x3f800000);
assert_eq!(
ulp_diff(std::f32::INFINITY, -std::f32::INFINITY),
0xff000000
);
assert_eq!(ulp_diff(0.0, f32::from_bits(0.0f32.to_bits() + 1)), 1);
assert_eq!(ulp_diff(-0.0, f32::from_bits(0.0f32.to_bits() + 1)), 1);
}
#[test]