Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

Commit 9c68f74

Browse files
committed
Add a generic version of round
This replaces `round` and `roundf`.
1 parent 220c8e5 commit 9c68f74

File tree

5 files changed

+54
-52
lines changed

5 files changed

+54
-52
lines changed

etc/function-definitions.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,12 +685,14 @@
685685
"round": {
686686
"sources": [
687687
"src/libm_helper.rs",
688+
"src/math/generic/round.rs",
688689
"src/math/round.rs"
689690
],
690691
"type": "f64"
691692
},
692693
"roundf": {
693694
"sources": [
695+
"src/math/generic/round.rs",
694696
"src/math/roundf.rs"
695697
],
696698
"type": "f32"

src/math/generic/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ mod fabs;
44
mod fdim;
55
mod floor;
66
mod rint;
7+
mod round;
78
mod scalbn;
89
mod sqrt;
910
mod trunc;
@@ -14,6 +15,7 @@ pub use fabs::fabs;
1415
pub use fdim::fdim;
1516
pub use floor::floor;
1617
pub use rint::rint;
18+
pub use round::round;
1719
pub use scalbn::scalbn;
1820
pub use sqrt::sqrt;
1921
pub use trunc::trunc;

src/math/generic/round.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
use super::super::{Float, MinInt};
2+
use super::{copysign, trunc};
3+
4+
pub fn round<F: Float>(x: F) -> F {
5+
let f0p5 = F::from_parts(false, F::EXP_BIAS - 1, F::Int::ZERO); // 0.5
6+
let f0p25 = F::from_parts(false, F::EXP_BIAS - 2, F::Int::ZERO); // 0.25
7+
8+
trunc(x + copysign(f0p5 - f0p25 * F::EPSILON, x))
9+
}
10+
11+
#[cfg(test)]
12+
mod tests {
13+
use super::*;
14+
15+
#[test]
16+
fn zeroes_f32() {
17+
assert_biteq!(round(0.0_f32), 0.0_f32);
18+
assert_biteq!(round(-0.0_f32), -0.0_f32);
19+
}
20+
21+
#[test]
22+
fn sanity_check_f32() {
23+
assert_eq!(round(-1.0_f32), -1.0);
24+
assert_eq!(round(2.8_f32), 3.0);
25+
assert_eq!(round(-0.5_f32), -1.0);
26+
assert_eq!(round(0.5_f32), 1.0);
27+
assert_eq!(round(-1.5_f32), -2.0);
28+
assert_eq!(round(1.5_f32), 2.0);
29+
}
30+
31+
#[test]
32+
fn zeroes_f64() {
33+
assert_biteq!(round(0.0_f64), 0.0_f64);
34+
assert_biteq!(round(-0.0_f64), -0.0_f64);
35+
}
36+
37+
#[test]
38+
fn sanity_check_f64() {
39+
assert_eq!(round(-1.0_f64), -1.0);
40+
assert_eq!(round(2.8_f64), 3.0);
41+
assert_eq!(round(-0.5_f64), -1.0);
42+
assert_eq!(round(0.5_f64), 1.0);
43+
assert_eq!(round(-1.5_f64), -2.0);
44+
assert_eq!(round(1.5_f64), 2.0);
45+
}
46+
}

src/math/round.rs

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,5 @@
1-
use core::f64;
2-
3-
use super::{copysign, trunc};
4-
1+
/// Round `x` to the nearest integer, breaking ties away from zero.
52
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
63
pub fn round(x: f64) -> f64 {
7-
trunc(x + copysign(0.5 - 0.25 * f64::EPSILON, x))
8-
}
9-
10-
#[cfg(test)]
11-
mod tests {
12-
use super::round;
13-
14-
#[test]
15-
fn negative_zero() {
16-
assert_eq!(round(-0.0_f64).to_bits(), (-0.0_f64).to_bits());
17-
}
18-
19-
#[test]
20-
fn sanity_check() {
21-
assert_eq!(round(-1.0), -1.0);
22-
assert_eq!(round(2.8), 3.0);
23-
assert_eq!(round(-0.5), -1.0);
24-
assert_eq!(round(0.5), 1.0);
25-
assert_eq!(round(-1.5), -2.0);
26-
assert_eq!(round(1.5), 2.0);
27-
}
4+
super::generic::round(x)
285
}

src/math/roundf.rs

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,5 @@
1-
use core::f32;
2-
3-
use super::{copysignf, truncf};
4-
1+
/// Round `x` to the nearest integer, breaking ties away from zero.
52
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
63
pub fn roundf(x: f32) -> f32 {
7-
truncf(x + copysignf(0.5 - 0.25 * f32::EPSILON, x))
8-
}
9-
10-
// PowerPC tests are failing on LLVM 13: https://github.com/rust-lang/rust/issues/88520
11-
#[cfg(not(target_arch = "powerpc64"))]
12-
#[cfg(test)]
13-
mod tests {
14-
use super::roundf;
15-
16-
#[test]
17-
fn negative_zero() {
18-
assert_eq!(roundf(-0.0_f32).to_bits(), (-0.0_f32).to_bits());
19-
}
20-
21-
#[test]
22-
fn sanity_check() {
23-
assert_eq!(roundf(-1.0), -1.0);
24-
assert_eq!(roundf(2.8), 3.0);
25-
assert_eq!(roundf(-0.5), -1.0);
26-
assert_eq!(roundf(0.5), 1.0);
27-
assert_eq!(roundf(-1.5), -2.0);
28-
assert_eq!(roundf(1.5), 2.0);
29-
}
4+
super::generic::round(x)
305
}

0 commit comments

Comments
 (0)