#[inline]
pub const fn rint(x: f64) -> f64 {
static TWO52: [f64; 2] = [
4.50359962737049600000e+15,
-4.50359962737049600000e+15,
];
let mut i0: i64 = x.to_bits() as i64;
let sx = (i0 >> 63) & 1;
let j0: i32 = (((i0 >> 52) & 0x7ff) - 0x3ff) as i32;
if j0 < 52 {
if j0 < 0 {
let w = TWO52[sx as usize] + x;
let t = w - TWO52[sx as usize];
i0 = t.to_bits() as i64;
let u = (i0 & (0x7fffffffffffffffu64 as i64)) | (sx << 63);
return f64::from_bits(u as u64);
}
} else {
return if j0 == 0x400 {
x + x
} else {
x
};
}
let w = TWO52[sx as usize] + x;
w - TWO52[sx as usize]
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_rintf() {
assert_eq!(rint(0f64), 0.0f64.round());
assert_eq!(rint(1f64), 1.0f64.round());
assert_eq!(rint(1.2f64), 1.2f64.round());
assert_eq!(rint(-1.2f64), (-1.2f64).round());
assert_eq!(rint(-1.6f64), (-1.6f64).round());
assert_eq!(rint(-1.5f64), (-1.5f64).round());
assert_eq!(rint(1.6f64), 1.6f64.round());
assert_eq!(rint(1.5f64), 1.5f64.round());
assert_eq!(rint(2.5f64), 2.0f64);
assert_eq!(rint(3.5f64), 4.0f64);
assert_eq!(rint(-2.5f64), -2.0f64);
assert_eq!(rint(-3.5f64), -4.0f64);
assert_eq!(rint(f64::INFINITY), f64::INFINITY);
assert_eq!(rint(f64::NEG_INFINITY), f64::NEG_INFINITY);
assert!(rint(f64::NAN).is_nan());
}
}