1use super::trunc;
2use crate::Real;
3
4pub const fn round(x: Real) -> Real {
9 const THRESHOLD: Real = (1u64 << 52) as Real;
10
11 if x >= 0.0 {
12 if x >= THRESHOLD { x } else { trunc(x + 0.5) }
13 } else if x <= -THRESHOLD {
14 x
15 } else {
16 trunc(x - 0.5)
17 }
18}
19
20#[cfg(feature = "std")]
21#[cfg(test)]
22mod tests {
23 use super::round;
24
25 #[test]
26 fn round_matches_std_round() {
27 let cases: &[f64] = &[
28 0.0,
29 -0.0,
30 0.1,
31 -0.1,
32 0.4,
33 -0.4,
34 0.5,
35 -0.5,
36 0.6,
37 -0.6,
38 1.3,
39 -1.3,
40 1.5,
41 -1.5,
42 2.5,
43 -2.5,
44 123.456,
45 -123.456,
46 4503599627370495.5, 4503599627370496.0, 4503599627370496.3,
49 9007199254740992.0, f64::INFINITY,
51 f64::NEG_INFINITY,
52 ];
53
54 for &x in cases {
55 let expected = x.round();
56 let got = round(x);
57 assert_eq!(got, expected, "round({}) mismatch", x);
58 }
59
60 assert!(round(f64::NAN).is_nan());
62 assert!(f64::NAN.round().is_nan());
63 }
64
65 #[test]
66 fn round_is_const() {
67 const _C1: f64 = round(1.7);
69 const _C2: f64 = round(-2.5);
70 const _C3: f64 = round(4503599627370496.7);
71 }
72}