]>
Commit | Line | Data |
---|---|---|
49aad941 FG |
1 | use core::f32; |
2 | ||
3 | /// Floor (f64) | |
4 | /// | |
5 | /// Finds the nearest integer less than or equal to `x`. | |
6 | #[inline] | |
7 | #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] | |
8 | pub fn floorf(x: f32) -> f32 { | |
9 | // On wasm32 we know that LLVM's intrinsic will compile to an optimized | |
10 | // `f32.floor` native instruction, so we can leverage this for both code size | |
11 | // and speed. | |
12 | llvm_intrinsically_optimized! { | |
13 | #[cfg(target_arch = "wasm32")] { | |
14 | return unsafe { ::core::intrinsics::floorf32(x) } | |
15 | } | |
16 | } | |
17 | let mut ui = x.to_bits(); | |
18 | let e = (((ui >> 23) as i32) & 0xff) - 0x7f; | |
19 | ||
20 | if e >= 23 { | |
21 | return x; | |
22 | } | |
23 | if e >= 0 { | |
24 | let m: u32 = 0x007fffff >> e; | |
25 | if (ui & m) == 0 { | |
26 | return x; | |
27 | } | |
28 | force_eval!(x + f32::from_bits(0x7b800000)); | |
29 | if ui >> 31 != 0 { | |
30 | ui += m; | |
31 | } | |
32 | ui &= !m; | |
33 | } else { | |
34 | force_eval!(x + f32::from_bits(0x7b800000)); | |
35 | if ui >> 31 == 0 { | |
36 | ui = 0; | |
37 | } else if ui << 1 != 0 { | |
38 | return -1.0; | |
39 | } | |
40 | } | |
41 | f32::from_bits(ui) | |
42 | } | |
43 | ||
44 | #[cfg(test)] | |
45 | mod tests { | |
46 | #[test] | |
47 | fn no_overflow() { | |
48 | assert_eq!(super::floorf(0.5), 0.0); | |
49 | } | |
50 | } |