From e586442a0a7d61c67c9b63d852efb5af7b041320 Mon Sep 17 00:00:00 2001 From: Nathan Vegdahl Date: Wed, 30 Oct 2019 21:05:01 +0900 Subject: [PATCH] Cleaned up floating point ulp code. The logic is much clearer now, and the code is more compact. --- src/fp_utils.rs | 56 ++++++++++++++++++------------------------------- 1 file changed, 20 insertions(+), 36 deletions(-) diff --git a/src/fp_utils.rs b/src/fp_utils.rs index 40aa252..756a940 100644 --- a/src/fp_utils.rs +++ b/src/fp_utils.rs @@ -13,36 +13,32 @@ pub fn fp_gamma(n: u32) -> f32 { } pub fn increment_ulp(v: f32) -> f32 { - // Handle special cases - if (v.is_infinite() && v > 0.0) || v.is_nan() { - return v; - } - - // Handle zero - let v = if v == -0.0 { 0.0 } else { v }; - - // Increase ulp by 1 - if v >= 0.0 { - bits_to_f32(f32_to_bits(v) + 1) + if v.is_finite() { + if v > 0.0 { + f32::from_bits(v.to_bits() + 1) + } else if v < -0.0 { + f32::from_bits(v.to_bits() - 1) + } else { + f32::from_bits(0x00_00_00_01) + } } else { - bits_to_f32(f32_to_bits(v) - 1) + // Infinity or NaN. + v } } pub fn decrement_ulp(v: f32) -> f32 { - // Handle special cases - if (v.is_infinite() && v < 0.0) || v.is_nan() { - return v; - } - - // Handle zero - let v = if v == 0.0 { -0.0 } else { v }; - - // Decrease ulp by 1 - if v <= -0.0 { - bits_to_f32(f32_to_bits(v) + 1) + if v.is_finite() { + if v > 0.0 { + f32::from_bits(v.to_bits() - 1) + } else if v < -0.0 { + f32::from_bits(v.to_bits() + 1) + } else { + f32::from_bits(0x80_00_00_01) + } } else { - bits_to_f32(f32_to_bits(v) - 1) + // Infinity or NaN. + v } } @@ -85,18 +81,6 @@ pub fn robust_ray_origin(pos: Point, pos_err: f32, nor: Normal, ray_dir: Vector) Point::new(x, y, z) } -#[inline(always)] -fn f32_to_bits(v: f32) -> u32 { - use std::mem::transmute_copy; - unsafe { transmute_copy::(&v) } -} - -#[inline(always)] -fn bits_to_f32(bits: u32) -> f32 { - use std::mem::transmute_copy; - unsafe { transmute_copy::(&bits) } -} - #[cfg(test)] mod tests { use super::*;