File tree 2 files changed +28
-62
lines changed
2 files changed +28
-62
lines changed Original file line number Diff line number Diff line change
1
+ use super :: copysign;
2
+ use super :: trunc;
1
3
use core:: f64;
2
4
3
- const TOINT : f64 = 1.0 / f64:: EPSILON ;
4
-
5
5
#[ cfg_attr( all( test, assert_no_panic) , no_panic:: no_panic) ]
6
- pub fn round ( mut x : f64 ) -> f64 {
7
- let i = x. to_bits ( ) ;
8
- let e: u64 = i >> 52 & 0x7ff ;
9
- let mut y: f64 ;
10
-
11
- if e >= 0x3ff + 52 {
12
- return x;
13
- }
14
- if e < 0x3ff - 1 {
15
- // raise inexact if x!=0
16
- force_eval ! ( x + TOINT ) ;
17
- return 0.0 * x;
18
- }
19
- if i >> 63 != 0 {
20
- x = -x;
21
- }
22
- y = x + TOINT - TOINT - x;
23
- if y > 0.5 {
24
- y = y + x - 1.0 ;
25
- } else if y <= -0.5 {
26
- y = y + x + 1.0 ;
27
- } else {
28
- y = y + x;
29
- }
30
-
31
- if i >> 63 != 0 {
32
- -y
33
- } else {
34
- y
35
- }
6
+ pub fn round ( x : f64 ) -> f64 {
7
+ trunc ( x + copysign ( 0.5 - 0.25 * f64:: EPSILON , x) )
36
8
}
37
9
38
10
#[ cfg( test) ]
@@ -43,4 +15,14 @@ mod tests {
43
15
fn negative_zero ( ) {
44
16
assert_eq ! ( round( -0.0_f64 ) . to_bits( ) , ( -0.0_f64 ) . to_bits( ) ) ;
45
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
+ }
46
28
}
Original file line number Diff line number Diff line change
1
+ use super :: copysignf;
2
+ use super :: truncf;
1
3
use core:: f32;
2
4
3
- const TOINT : f32 = 1.0 / f32:: EPSILON ;
4
-
5
5
#[ cfg_attr( all( test, assert_no_panic) , no_panic:: no_panic) ]
6
- pub fn roundf ( mut x : f32 ) -> f32 {
7
- let i = x. to_bits ( ) ;
8
- let e: u32 = i >> 23 & 0xff ;
9
- let mut y: f32 ;
10
-
11
- if e >= 0x7f + 23 {
12
- return x;
13
- }
14
- if e < 0x7f - 1 {
15
- force_eval ! ( x + TOINT ) ;
16
- return 0.0 * x;
17
- }
18
- if i >> 31 != 0 {
19
- x = -x;
20
- }
21
- y = x + TOINT - TOINT - x;
22
- if y > 0.5f32 {
23
- y = y + x - 1.0 ;
24
- } else if y <= -0.5f32 {
25
- y = y + x + 1.0 ;
26
- } else {
27
- y = y + x;
28
- }
29
- if i >> 31 != 0 {
30
- -y
31
- } else {
32
- y
33
- }
6
+ pub fn roundf ( x : f32 ) -> f32 {
7
+ truncf ( x + copysignf ( 0.5 - 0.25 * f32:: EPSILON , x) )
34
8
}
35
9
36
10
#[ cfg( test) ]
@@ -41,4 +15,14 @@ mod tests {
41
15
fn negative_zero ( ) {
42
16
assert_eq ! ( roundf( -0.0_f32 ) . to_bits( ) , ( -0.0_f32 ) . to_bits( ) ) ;
43
17
}
18
+
19
+ #[ test]
20
+ fn sanity_check ( ) {
21
+ assert_eq ! ( roundf( -1.0 ) , -1.0 ) ;
22
+ assert_eq ! ( roundf( 2.8 ) , 3.0 ) ;
23
+ assert_eq ! ( roundf( -0.5 ) , -1.0 ) ;
24
+ assert_eq ! ( roundf( 0.5 ) , 1.0 ) ;
25
+ assert_eq ! ( roundf( -1.5 ) , -2.0 ) ;
26
+ assert_eq ! ( roundf( 1.5 ) , 2.0 ) ;
27
+ }
44
28
}
You can’t perform that action at this time.
0 commit comments