]>
Commit | Line | Data |
---|---|---|
8faf50e0 XL |
1 | use core::f32; |
2 | ||
3 | const TOINT: f32 = 1.0 / f32::EPSILON; | |
4 | ||
48663c56 | 5 | #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] |
8faf50e0 XL |
6 | pub fn roundf(mut x: f32) -> f32 { |
7 | let i = x.to_bits(); | |
8 | let e: u32 = i >> 23 & 0xff; | |
9 | let mut y: f32; | |
10 | ||
11 | if e >= 0x7f + 23 { | |
12 | return x; | |
13 | } | |
8faf50e0 XL |
14 | if e < 0x7f - 1 { |
15 | force_eval!(x + TOINT); | |
16 | return 0.0 * x; | |
17 | } | |
60c5eb7d XL |
18 | if i >> 31 != 0 { |
19 | x = -x; | |
20 | } | |
8faf50e0 XL |
21 | y = x + TOINT - TOINT - x; |
22 | if y > 0.5f32 { | |
23 | y = y + x - 1.0; | |
24 | } else if y <= -0.5f32 { | |
25 | y = y + x + 1.0; | |
26 | } else { | |
27 | y = y + x; | |
28 | } | |
29 | if i >> 31 != 0 { | |
30 | -y | |
31 | } else { | |
32 | y | |
33 | } | |
34 | } | |
60c5eb7d XL |
35 | |
36 | #[cfg(test)] | |
37 | mod tests { | |
38 | use super::roundf; | |
39 | ||
40 | #[test] | |
41 | fn negative_zero() { | |
42 | assert_eq!(roundf(-0.0_f32).to_bits(), (-0.0_f32).to_bits()); | |
43 | } | |
44 | } |