@@ -108,7 +108,7 @@ pub fn divmod(v1: f64, v2: f64) -> Option<(f64, f64)> {
108
108
109
109
// nextafter algorithm based off of https://gitlab.com/bronsonbdevost/next_afterf
110
110
#[ allow( clippy:: float_cmp) ]
111
- pub fn nextafter ( x : f64 , y : f64 , steps : Option < u64 > ) -> f64 {
111
+ pub fn nextafter ( x : f64 , y : f64 ) -> f64 {
112
112
if x == y {
113
113
y
114
114
} else if x. is_nan ( ) || y. is_nan ( ) {
@@ -120,69 +120,79 @@ pub fn nextafter(x: f64, y: f64, steps: Option<u64>) -> f64 {
120
120
} else if x == 0.0 {
121
121
f64:: from_bits ( 1 ) . copysign ( y)
122
122
} else {
123
- return match steps {
124
- None => {
125
- // next x after 0 if y is farther from 0 than x, otherwise next towards 0
126
- // the sign is a separate bit in floats, so bits+1 moves away from 0 no matter the float
127
- let b = x. to_bits ( ) ;
128
- let bits = if ( y > x) == ( x > 0.0 ) { b + 1 } else { b - 1 } ;
129
- let ret = f64:: from_bits ( bits) ;
130
- if ret == 0.0 {
131
- ret. copysign ( x)
10000
span>
132
- } else {
133
- ret
134
- }
135
- }
136
- Some ( steps) => {
137
- if steps == 0 {
138
- return x;
139
- }
123
+ // next x after 0 if y is farther from 0 than x, otherwise next towards 0
124
+ // the sign is a separate bit in floats, so bits+1 moves away from 0 no matter the float
125
+ let b = x. to_bits ( ) ;
126
+ let bits = if ( y > x) == ( x > 0.0 ) { b + 1 } else { b - 1 } ;
127
+ let ret = f64:: from_bits ( bits) ;
128
+ if ret == 0.0 {
129
+ ret. copysign ( x)
130
+ } else {
131
+ ret
132
+ }
133
+ }
134
+ }
140
135
141
- if x. is_nan ( ) {
142
- return x;
143
- }
136
+ #[ allow( clippy:: float_cmp) ]
137
+ pub fn nextafter_with_steps ( x : f64 , y : f64 , steps : u64 ) -> f64 {
138
+ if x == y {
139
+ y
140
+ } else if x. is_nan ( ) || y. is_nan ( ) {
141
+ f64:: NAN
142
+ } else if x >= f64:: INFINITY {
143
+ f64:: MAX
144
+ } else if x <= f64:: NEG_INFINITY {
145
+ f64:: MIN
146
+ } else if x == 0.0 {
147
+ f64:: from_bits ( 1 ) . copysign ( y)
148
+ } else {
149
+ if steps == 0 {
150
+ return x;
151
+ }
144
152
145
- if y . is_nan ( ) {
146
- return y ;
147
- }
153
+ if x . is_nan ( ) {
154
+ return x ;
155
+ }
148
156
149
- let sign_bit: u64 = 1 << 63 ;
157
+ if y. is_nan ( ) {
158
+ return y;
159
+ }
150
160
151
- let mut ux = x. to_bits ( ) ;
152
- let uy = y. to_bits ( ) ;
161
+ let sign_bit: u64 = 1 << 63 ;
153
162
154
- let ax = ux & !sign_bit ;
155
- let ay = uy & !sign_bit ;
163
+ let mut ux = x . to_bits ( ) ;
164
+ let uy = y . to_bits ( ) ;
156
165
157
- // If signs are different
158
- if ( ( ux ^ uy) & sign_bit) != 0 {
159
- return if ax + ay <= steps {
<
685C
code>160
- f64:: from_bits ( uy)
161
- } else if ax < steps {
162
- let result = ( uy & sign_bit) | ( steps - ax) ;
163
- f64:: from_bits ( result)
164
- } else {
165
- ux -= steps;
166
- f64:: from_bits ( ux)
167
- } ;
168
- }
166
+ let ax = ux & !sign_bit;
167
+ let ay = uy & !sign_bit;
169
168
170
- // If signs are the same
171
- if ax > ay {
172
- if ax - ay >= steps {
173
- ux -= steps;
174
- f64:: from_bits ( ux)
175
- } else {
176
- f64:: from_bits ( uy)
177
- }
178
- } else if ay - ax >= steps {
179
- ux += steps;
180
- f64:: from_bits ( ux)
181
- } else {
182
- f64:: from_bits ( uy)
183
- }
169
+ // If signs are different
170
+ if ( ( ux ^ uy) & sign_bit) != 0 {
171
+ return if ax + ay <= steps {
172
+ f64:: from_bits ( uy)
173
+ } else if ax < steps {
174
+ let result = ( uy & sign_bit) | ( steps - ax) ;
175
+ f64:: from_bits ( result)
176
+ } else {
177
+ ux -= steps;
178
+ f64:: from_bits ( ux)
179
+ } ;
180
+ }
181
+
182
+ // If signs are the same
183
+ if ax > ay {
184
+ if ax - ay >= steps {
185
+ ux -= steps;
186
+ f64:: from_bits ( ux)
187
+ } else {
188
+ f64:: from_bits ( uy)
184
189
}
185
- } ;
190
+ } else if ay - ax >= steps {
191
+ ux += steps;
192
+ f64:: from_bits ( ux)
193
+ } else {
194
+ f64:: from_bits ( uy)
195
+ }
186
196
}
187
197
}
188
198
@@ -191,10 +201,10 @@ pub fn ulp(x: f64) -> f64 {
191
201
return x;
192
202
}
193
203
let x = x. abs ( ) ;
194
- let x2 = nextafter ( x, f64:: INFINITY , None ) ;
204
+ let x2 = nextafter ( x, f64:: INFINITY ) ;
195
205
if x2. is_infinite ( ) {
196
206
// special case: x is the largest positive representable float
197
- let x2 = nextafter ( x, f64:: NEG_INFINITY , None ) ;
207
+ let x2 = nextafter ( x, f64:: NEG_INFINITY ) ;
198
208
x - x2
199
209
} else {
200
210
x2 - x
0 commit comments