1 #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] rint(x: f64) -> f642pub fn rint(x: f64) -> f64 { 3 let one_over_e = 1.0 / f64::EPSILON; 4 let as_u64: u64 = x.to_bits(); 5 let exponent: u64 = as_u64 >> 52 & 0x7ff; 6 let is_positive = (as_u64 >> 63) == 0; 7 if exponent >= 0x3ff + 52 { 8 x 9 } else { 10 let ans = if is_positive { 11 x + one_over_e - one_over_e 12 } else { 13 x - one_over_e + one_over_e 14 }; 15 16 if ans == 0.0 { 17 if is_positive { 18 0.0 19 } else { 20 -0.0 21 } 22 } else { 23 ans 24 } 25 } 26 } 27 28 // PowerPC tests are failing on LLVM 13: https://github.com/rust-lang/rust/issues/88520 29 #[cfg(not(target_arch = "powerpc64"))] 30 #[cfg(test)] 31 mod tests { 32 use super::rint; 33 34 #[test] negative_zero()35 fn negative_zero() { 36 assert_eq!(rint(-0.0_f64).to_bits(), (-0.0_f64).to_bits()); 37 } 38 39 #[test] sanity_check()40 fn sanity_check() { 41 assert_eq!(rint(-1.0), -1.0); 42 assert_eq!(rint(2.8), 3.0); 43 assert_eq!(rint(-0.5), -0.0); 44 assert_eq!(rint(0.5), 0.0); 45 assert_eq!(rint(-1.5), -2.0); 46 assert_eq!(rint(1.5), 2.0); 47 } 48 } 49