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

Commit 933d9b0

Browse files
authored
Merge pull request #465 from tgross35/generic-round
Add `roundf16` and `roundf128`
2 parents 220c8e5 + 581db99 commit 933d9b0

File tree

15 files changed

+132
-57
lines changed

15 files changed

+132
-57
lines changed

crates/libm-macros/src/shared.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option<Signature>, &[&str])]
99
FloatTy::F16,
1010
Signature { args: &[Ty::F16], returns: &[Ty::F16] },
1111
None,
12-
&["ceilf16", "fabsf16", "floorf16", "rintf16", "sqrtf16", "truncf16"],
12+
&["ceilf16", "fabsf16", "floorf16", "rintf16", "roundf16", "sqrtf16", "truncf16"],
1313
),
1414
(
1515
// `fn(f32) -> f32`
@@ -40,7 +40,7 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option<Signature>, &[&str])]
4040
FloatTy::F128,
4141
Signature { args: &[Ty::F128], returns: &[Ty::F128] },
4242
None,
43-
&["ceilf128", "fabsf128", "floorf128", "rintf128", "sqrtf128", "truncf128"],
43+
&["ceilf128", "fabsf128", "floorf128", "rintf128", "roundf128", "sqrtf128", "truncf128"],
4444
),
4545
(
4646
// `(f16, f16) -> f16`

crates/libm-test/benches/random.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ libm_macros::for_each_function! {
129129
| floorf16
130130
| rintf128
131131
| rintf16
132+
| roundf128
133+
| roundf16
132134
| sqrtf128
133135
| sqrtf16
134136
| truncf128

crates/libm-test/src/mpfloat.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ libm_macros::for_each_function! {
175175
rintf16,
176176
round,
177177
roundf,
178+
roundf128,
179+
roundf16,
178180
scalbn,
179181
scalbnf,
180182
sincos,sincosf,
@@ -247,6 +249,7 @@ impl_no_round! {
247249
fabsf16 => abs_mut;
248250
floorf16 => floor_mut;
249251
rintf16 => round_even_mut; // FIXME: respect rounding mode
252+
roundf16 => round_mut;
250253
truncf16 => trunc_mut;
251254
}
252255

@@ -256,6 +259,7 @@ impl_no_round! {
256259
fabsf128 => abs_mut;
257260
floorf128 => floor_mut;
258261
rintf128 => round_even_mut; // FIXME: respect rounding mode
262+
roundf128 => round_mut;
259263
truncf128 => trunc_mut;
260264
}
261265

crates/libm-test/src/precision.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ use crate::{BaseName, CheckBasis, CheckCtx, Float, Identifier, Int, TestResult};
1313
pub struct SpecialCase;
1414

1515
/// ULP allowed to differ from the results returned by a test basis.
16-
///
17-
/// Note that these results were obtained using 400M rounds of random inputs, which
18-
/// is not a value used by default.
1916
pub fn default_ulp(ctx: &CheckCtx) -> u32 {
2017
// ULP compared to the infinite (MPFR) result.
2118
let mut ulp = match ctx.base_name {

crates/libm-test/tests/compare_built_musl.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ libm_macros::for_each_function! {
9191
floorf16,
9292
rintf128,
9393
rintf16,
94+
roundf128,
95+
roundf16,
9496
sqrtf128,
9597
sqrtf16,
9698
truncf128,

crates/util/src/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ fn do_eval(basis: &str, op: &str, inputs: &[&str]) {
9898
| floorf16
9999
| rintf128
100100
| rintf16
101+
| roundf128
102+
| roundf16
101103
| sqrtf128
102104
| sqrtf16
103105
| truncf128

etc/function-definitions.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,16 +685,32 @@
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"
697699
},
700+
"roundf128": {
701+
"sources": [
702+
"src/math/generic/round.rs",
703+
"src/math/roundf128.rs"
704+
],
705+
"type": "f128"
706+
},
707+
"roundf16": {
708+
"sources": [
709+
"src/math/generic/round.rs",
710+
"src/math/roundf16.rs"
711+
],
712+
"type": "f16"
713+
},
698714
"scalbn": {
699715
"sources": [
700716
"src/libm_helper.rs",

etc/function-list.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ rintf128
101101
rintf16
102102
round
103103
roundf
104+
roundf128
105+
roundf16
104106
scalbn
105107
scalbnf
106108
sin

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: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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+
#[cfg(f16_enabled)]
17+
fn zeroes_f16() {
18+
assert_biteq!(round(0.0_f16), 0.0_f16);
19+
assert_biteq!(round(-0.0_f16), -0.0_f16);
20+
}
21+
22+
#[test]
23+
#[cfg(f16_enabled)]
24+
fn sanity_check_f16() {
25+
assert_eq!(round(-1.0_f16), -1.0);
26+
assert_eq!(round(2.8_f16), 3.0);
27+
assert_eq!(round(-0.5_f16), -1.0);
28+
assert_eq!(round(0.5_f16), 1.0);
29+
assert_eq!(round(-1.5_f16), -2.0);
30+
assert_eq!(round(1.5_f16), 2.0);
31+
}
32+
33+
#[test]
34+
fn zeroes_f32() {
35+
assert_biteq!(round(0.0_f32), 0.0_f32);
36+
assert_biteq!(round(-0.0_f32), -0.0_f32);
37+
}
38+
39+
#[test]
40+
fn sanity_check_f32() {
41+
assert_eq!(round(-1.0_f32), -1.0);
42+
assert_eq!(round(2.8_f32), 3.0);
43+
assert_eq!(round(-0.5_f32), -1.0);
44+
assert_eq!(round(0.5_f32), 1.0);
45+
assert_eq!(round(-1.5_f32), -2.0);
46+
assert_eq!(round(1.5_f32), 2.0);
47+
}
48+
49+
#[test]
50+
fn zeroes_f64() {
51+
assert_biteq!(round(0.0_f64), 0.0_f64);
52+
assert_biteq!(round(-0.0_f64), -0.0_f64);
53+
}
54+
55+
#[test]
56+
fn sanity_check_f64() {
57+
assert_eq!(round(-1.0_f64), -1.0);
58+
assert_eq!(round(2.8_f64), 3.0);
59+
assert_eq!(round(-0.5_f64), -1.0);
60+
assert_eq!(round(0.5_f64), 1.0);
61+
assert_eq!(round(-1.5_f64), -2.0);
62+
assert_eq!(round(1.5_f64), 2.0);
63+
}
64+
65+
#[test]
66+
#[cfg(f128_enabled)]
67+
fn zeroes_f128() {
68+
assert_biteq!(round(0.0_f128), 0.0_f128);
69+
assert_biteq!(round(-0.0_f128), -0.0_f128);
70+
}
71+
72+
#[test]
73+
#[cfg(f128_enabled)]
74+
fn sanity_check_f128() {
75+
assert_eq!(round(-1.0_f128), -1.0);
76+
assert_eq!(round(2.8_f128), 3.0);
77+
assert_eq!(round(-0.5_f128), -1.0);
78+
assert_eq!(round(0.5_f128), 1.0);
79+
assert_eq!(round(-1.5_f128), -2.0);
80+
assert_eq!(round(1.5_f128), 2.0);
81+
}
82+
}

0 commit comments

Comments
 (0)