This repository was archived by the owner on Apr 28, 2025. It is now read-only.
File tree Expand file tree Collapse file tree 3 files changed +81
-0
lines changed Expand file tree Collapse file tree 3 files changed +81
-0
lines changed Original file line number Diff line number Diff line change 1
1
macro_rules! force_eval {
2
2
( $e: expr) => {
3
+ #[ allow( unused_unsafe) ]
3
4
unsafe {
4
5
:: core:: ptr:: read_volatile( & $e) ;
5
6
}
@@ -146,6 +147,8 @@ mod log2f;
146
147
mod logf;
147
148
mod modf;
148
149
mod modff;
150
+ mod nextafter;
151
+ mod nextafterf;
149
152
mod pow;
150
153
mod powf;
151
154
mod remainder;
@@ -258,6 +261,8 @@ pub use self::log2f::log2f;
258
261
pub use self :: logf:: logf;
259
262
pub use self :: modf:: modf;
260
263
pub use self :: modff:: modff;
264
+ pub use self :: nextafter:: nextafter;
265
+ pub use self :: nextafterf:: nextafterf;
261
266
pub use self :: pow:: pow;
262
267
pub use self :: powf:: powf;
263
268
pub use self :: remainder:: remainder;
Original file line number Diff line number Diff line change
1
+ #[ inline]
2
+ #[ cfg_attr( all( test, assert_no_panic) , no_panic:: no_panic) ]
3
+ pub extern "C" fn nextafter ( x : f64 , y : f64 ) -> f64 {
4
+ if x. is_nan ( ) || y. is_nan ( ) {
5
+ return x + y;
6
+ }
7
+
8
+ let mut ux_i = x. to_bits ( ) ;
9
+ let uy_i = y. to_bits ( ) ;
10
+ if ux_i == uy_i {
11
+ return y;
12
+ }
13
+
14
+ let ax = ux_i & !1_u64 / 2 ;
15
+ let ay = uy_i & !1_u64 / 2 ;
16
+ if ax == 0 {
17
+ if ay == 0 {
18
+ return y;
19
+ }
20
+ ux_i = ( uy_i & 1_u64 << 63 ) | 1 ;
21
+ } else if ax > ay || ( ( ux_i ^ uy_i) & 1_u64 << 63 ) != 0 {
22
+ ux_i -= 1 ;
23
+ } else {
24
+ ux_i += 1 ;
25
+ }
26
+
27
+ let e = ux_i. wrapping_shr ( 52 & 0x7ff ) ;
28
+ // raise overflow if ux.f is infinite and x is finite
29
+ if e == 0x7ff {
30
+ force_eval ! ( x + x) ;
31
+ }
32
+ let ux_f = f64:: from_bits ( ux_i) ;
33
+ // raise underflow if ux.f is subnormal or zero
34
+ if e == 0 {
35
+ force_eval ! ( x * x + ux_f * ux_f) ;
36
+ }
37
+ ux_f
38
+ }
Original file line number Diff line number Diff line change
1
+ #[ inline]
2
+ #[ cfg_attr( all( test, assert_no_panic) , no_panic:: no_panic) ]
3
+ pub extern "C" fn nextafterf ( x : f32 , y : f32 ) -> f32 {
4
+ if x. is_nan ( ) || y. is_nan ( ) {
5
+ return x + y;
6
+ }
7
+
8
+ let mut ux_i = x. to_bits ( ) ;
9
+ let uy_i = y. to_bits ( ) ;
10
+ if ux_i == uy_i {
11
+ return y;
12
+ }
13
+
14
+ let ax = ux_i & 0x7fff_ffff_u32 ;
15
+ let ay = uy_i & 0x7fff_ffff_u32 ;
16
+ if ax == 0 {
17
+ if ay == 0 {
18
+ return y;
19
+ }
20
+ ux_i = ( uy_i & 0x8000_0000_u32 ) | 1 ;
21
+ } else if ax > ay || ( ( ux_i ^ uy_i) & 0x8000_0000_u32 ) != 0 {
22
+ ux_i -= 1 ;
23
+ } else {
24
+ ux_i += 1 ;
25
+ }
26
+
27
+ let e = ux_i. wrapping_shr ( 0x7f80_0000_u32 ) ;
28
+ // raise overflow if ux_f is infinite and x is finite
29
+ if e == 0x7f80_0000_u32 {
30
+ force_eval ! ( x + x) ;
31
+ }
32
+ let ux_f = f32:: from_bits ( ux_i) ;
33
+ // raise underflow if ux_f is subnormal or zero
34
+ if e == 0 {
35
+ force_eval ! ( x * x + ux_f * ux_f) ;
36
+ }
37
+ ux_f
38
+ }
You can’t perform that action at this time.
0 commit comments