• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use core::f64;
2 
3 const TOINT: f64 = 1.0 / f64::EPSILON;
4 
5 #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
round(mut x: f64) -> f646 pub fn round(mut x: f64) -> f64 {
7     let i = x.to_bits();
8     let e: u64 = i >> 52 & 0x7ff;
9     let mut y: f64;
10 
11     if e >= 0x3ff + 52 {
12         return x;
13     }
14     if e < 0x3ff - 1 {
15         // raise inexact if x!=0
16         force_eval!(x + TOINT);
17         return 0.0 * x;
18     }
19     if i >> 63 != 0 {
20         x = -x;
21     }
22     y = x + TOINT - TOINT - x;
23     if y > 0.5 {
24         y = y + x - 1.0;
25     } else if y <= -0.5 {
26         y = y + x + 1.0;
27     } else {
28         y = y + x;
29     }
30 
31     if i >> 63 != 0 {
32         -y
33     } else {
34         y
35     }
36 }
37 
38 #[cfg(test)]
39 mod tests {
40     use super::round;
41 
42     #[test]
negative_zero()43     fn negative_zero() {
44         assert_eq!(round(-0.0_f64).to_bits(), (-0.0_f64).to_bits());
45     }
46 }
47