Skip to main content

deep_time/math/
floor.rs

1#![allow(clippy::indexing_slicing)]
2#![allow(clippy::excessive_precision)]
3#![allow(clippy::approx_constant)]
4#![allow(clippy::eq_op)]
5
6use crate::Real;
7
8/// Floor function for Real.
9///
10/// This implementation uses bit manipulation for safety and correctness in const contexts.
11/// It does not track inexact status.
12pub const fn floor_f(x: Real) -> Real {
13    // Handle special cases
14    if x.is_nan() || x.is_infinite() {
15        return x;
16    }
17    if x == 0.0 {
18        return x; // preserve signed zero
19    }
20
21    let bits = x.to_bits();
22    let sign = bits >> 63; // 0 = positive, 1 = negative
23    let exp = ((bits >> 52) & 0x7ff) as i32 - 1023;
24
25    // |x| < 1.0
26    if exp < 0 {
27        return if sign == 1 { -1.0 } else { 0.0 };
28    }
29
30    // Already an integer, or |x| is so large that it has no fractional bits
31    if exp >= 52 {
32        return x;
33    }
34
35    // Create mask to clear fractional bits
36    let frac_bits = 52 - exp;
37    let mask = (1u64 << frac_bits) - 1;
38    let cleared = bits & !mask;
39
40    let result = Real::from_bits(cleared);
41
42    // For negative numbers: if we had any fractional part, we must subtract 1
43    // to round toward negative infinity.
44    if sign == 1 && cleared != bits {
45        result - 1.0
46    } else {
47        result
48    }
49}