const_soft_float/soft_f64/
floor.rs1use super::{
2 helpers::{eq, gt},
3 SoftF64,
4};
5
6const TOINT: SoftF64 = SoftF64(1.0).div(SoftF64(f64::EPSILON));
7
8pub const fn floor(x: SoftF64) -> SoftF64 {
12 let ui = x.to_bits();
13 let e = ((ui >> 52) & 0x7ff) as i32;
14
15 if (e >= 0x3ff + 52) || eq(x, SoftF64::ZERO) {
16 return x;
17 }
18 let y = if (ui >> 63) != 0 {
20 x.sub(TOINT).add(TOINT).sub(x)
21 } else {
22 x.add(TOINT).sub(TOINT).sub(x)
23 };
24 if e < 0x3ff {
26 return if (ui >> 63) != 0 {
27 SoftF64(-1.0)
28 } else {
29 SoftF64::ZERO
30 };
31 }
32 if gt(y, SoftF64::ZERO) {
33 x.add(y).sub(SoftF64::ONE)
34 } else {
35 x.add(y)
36 }
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42
43 #[test]
44 fn sanity_check() {
45 assert_eq!(floor(SoftF64(1.1)).0, 1.0);
46 assert_eq!(floor(SoftF64(2.9)).0, 2.0);
47 }
48
49 #[test]
51 fn spec_tests() {
52 assert!(floor(SoftF64(f64::NAN)).0.is_nan());
54 for f in [0.0, -0.0, f64::INFINITY, f64::NEG_INFINITY]
55 .iter()
56 .copied()
57 {
58 assert_eq!(floor(SoftF64(f)).0, f);
59 }
60 }
61}