Cleaned up floating point ulp code.

The logic is much clearer now, and the code is more compact.
This commit is contained in:
Nathan Vegdahl 2019-10-30 21:05:01 +09:00
parent 1aeb3ed7ff
commit e586442a0a

View File

@ -13,36 +13,32 @@ pub fn fp_gamma(n: u32) -> f32 {
} }
pub fn increment_ulp(v: f32) -> f32 { pub fn increment_ulp(v: f32) -> f32 {
// Handle special cases if v.is_finite() {
if (v.is_infinite() && v > 0.0) || v.is_nan() { if v > 0.0 {
return v; f32::from_bits(v.to_bits() + 1)
} } else if v < -0.0 {
f32::from_bits(v.to_bits() - 1)
// Handle zero } else {
let v = if v == -0.0 { 0.0 } else { v }; f32::from_bits(0x00_00_00_01)
}
// Increase ulp by 1
if v >= 0.0 {
bits_to_f32(f32_to_bits(v) + 1)
} else { } else {
bits_to_f32(f32_to_bits(v) - 1) // Infinity or NaN.
v
} }
} }
pub fn decrement_ulp(v: f32) -> f32 { pub fn decrement_ulp(v: f32) -> f32 {
// Handle special cases if v.is_finite() {
if (v.is_infinite() && v < 0.0) || v.is_nan() { if v > 0.0 {
return v; f32::from_bits(v.to_bits() - 1)
} } else if v < -0.0 {
f32::from_bits(v.to_bits() + 1)
// Handle zero } else {
let v = if v == 0.0 { -0.0 } else { v }; f32::from_bits(0x80_00_00_01)
}
// Decrease ulp by 1
if v <= -0.0 {
bits_to_f32(f32_to_bits(v) + 1)
} else { } 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) Point::new(x, y, z)
} }
#[inline(always)]
fn f32_to_bits(v: f32) -> u32 {
use std::mem::transmute_copy;
unsafe { transmute_copy::<f32, u32>(&v) }
}
#[inline(always)]
fn bits_to_f32(bits: u32) -> f32 {
use std::mem::transmute_copy;
unsafe { transmute_copy::<u32, f32>(&bits) }
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;