This repository was archived by the owner on Apr 28, 2025. It is now read-only.
File tree Expand file tree Collapse file tree 4 files changed +107
-0
lines changed Expand file tree Collapse file tree 4 files changed +107
-0
lines changed Original file line number Diff line number Diff line change @@ -39,6 +39,9 @@ mod musl_reference_tests {
39
39
"jnf.rs" ,
40
40
"j1.rs" ,
41
41
"j1f.rs" ,
42
+ // musl doens't have these
43
+ "roundeven.rs" ,
44
+ "roundevenf.rs" ,
42
45
] ;
43
46
44
47
struct Function {
Original file line number Diff line number Diff line change @@ -171,6 +171,8 @@ mod remainderf;
171
171
mod remquo;
172
172
mod remquof;
173
173
mod round;
174
+ mod roundeven;
175
+ mod roundevenf;
174
176
mod roundf;
175
177
mod scalbn;
176
178
mod scalbnf;
@@ -285,6 +287,8 @@ pub use self::remainderf::remainderf;
285
287
pub use self :: remquo:: remquo;
286
288
pub use self :: remquof:: remquof;
287
289
pub use self :: round:: round;
290
+ pub use self :: roundeven:: roundeven;
291
+ pub use self :: roundevenf:: roundevenf;
288
292
pub use self :: roundf:: roundf;
289
293
pub use self :: scalbn:: scalbn;
290
294
pub use self :: scalbnf:: scalbnf;
Original file line number Diff line number Diff line change
1
+ // Source: musl libm rint
2
+ // (equivalent to roundeven when rounding mode is default,
3
+ // which Rust assumes)
4
+
5
+ #[ cfg_attr( all( test, assert_no_panic) , no_panic:: no_panic) ]
6
+ pub fn roundeven ( x : f64 ) -> f64 {
7
+ let one_over_e = 1.0 / f64:: EPSILON ;
8
+ let as_u64: u64 = x. to_bits ( ) ;
9
+ let exponent: u64 = as_u64 >> 52 & 0x7ff ;
10
+ let is_positive = ( as_u64 >> 63 ) == 0 ;
11
+ if exponent >= 0x3ff + 52 {
12
+ x
13
+ } else {
14
+ let ans = if is_positive {
15
+ x + one_over_e - one_over_e
16
+ } else {
17
+ x - one_over_e + one_over_e
18
+ } ;
19
+
20
+ if ans == 0.0 {
21
+ if is_positive {
22
+ 0.0
23
+ } else {
24
+ -0.0
25
+ }
26
+ } else {
27
+ ans
28
+ }
29
+ }
30
+ }
31
+
32
+ #[ cfg( test) ]
33
+ mod tests {
34
+ use super :: roundeven;
35
+
36
+ #[ test]
37
+ fn negative_zero ( ) {
38
+ assert_eq ! ( roundeven( -0.0_f64 ) . to_bits( ) , ( -0.0_f64 ) . to_bits( ) ) ;
39
+ }
40
+
41
+ #[ test]
42
+ fn sanity_check ( ) {
43
+ assert_eq ! ( roundeven( -1.0 ) , -1.0 ) ;
44
+ assert_eq ! ( roundeven( 2.8 ) , 3.0 ) ;
45
+ assert_eq ! ( roundeven( -0.5 ) , -0.0 ) ;
46
+ assert_eq ! ( roundeven( 0.5 ) , 0.0 ) ;
47
+ assert_eq ! ( roundeven( -1.5 ) , -2.0 ) ;
48
+ assert_eq ! ( roundeven( 1.5 ) , 2.0 ) ;
49
+ }
50
+ }
Original file line number Diff line number Diff line change
1
+ // Source: musl libm rintf
2
+ // (equivalent to roundevenf when rounding mode is default,
3
+ // which Rust assumes)
4
+
5
+ #[ cfg_attr( all( test, assert_no_panic) , no_panic:: no_panic) ]
6
+ pub fn roundevenf ( x : f32 ) -> f32 {
7
+ let one_over_e = 1.0 / f32:: EPSILON ;
8
+ let as_u32: u32 = x. to_bits ( ) ;
9
+ let exponent: u32 = as_u32 >> 23 & 0xff ;
10
+ let is_positive = ( as_u32 >> 31 ) == 0 ;
11
+ if exponent >= 0x7f + 23 {
12
+ x
13
+ } else {
14
+ let ans = if is_positive {
15
+ x + one_over_e - one_over_e
16
+ } else {
17
+ x - one_over_e + one_over_e
18
+ } ;
19
+
20
+ if ans == 0.0 {
21
+ if is_positive {
22
+ 0.0
23
+ } else {
24
+ -0.0
25
+ }
26
+ } else {
27
+ ans
28
+ }
29
+ }
30
+ }
31
+
32
+ #[ cfg( test) ]
33
+ mod tests {
34
+ use super :: roundevenf;
35
+
36
+ #[ test]
37
+ fn negative_zero ( ) {
38
+ assert_eq ! ( roundevenf( -0.0_f32 ) . to_bits( ) , ( -0.0_f32 ) . to_bits( ) ) ;
39
+ }
40
+
41
+ #[ test]
42
+ fn sanity_check ( ) {
43
+ assert_eq ! ( roundevenf( -1.0 ) , -1.0 ) ;
44
+ assert_eq ! ( roundevenf( 2.8 ) , 3.0 ) ;
45
+ assert_eq ! ( roundevenf( -0.5 ) , -0.0 ) ;
46
+ assert_eq ! ( roundevenf( 0.5 ) , 0.0 ) ;
47
+ assert_eq ! ( roundevenf( -1.5 ) , -2.0 ) ;
48
+ assert_eq ! ( roundevenf( 1.5 ) , 2.0 ) ;
49
+ }
50
+ }
You can’t perform that action at this time.
0 commit comments