@@ -162,6 +162,7 @@ impl<F> FloatExt for F where F: Float {}
162
162
pub trait FloatExt : Float {
163
163
const TINY_BITS : Self :: Int = Self :: Int :: ONE ;
164
164
165
+ /// Increment by one ULP, saturating at infinity.
165
166
fn next_up ( self ) -> Self {
166
167
let bits = self . to_bits ( ) ;
167
168
if self . is_nan ( ) || bits == Self :: INFINITY . to_bits ( ) {
@@ -182,6 +183,7 @@ pub trait FloatExt: Float {
182
183
Self :: from_bits ( next_bits)
183
184
}
184
185
186
+ /// A faster version of `next_up` when skipping a specified number of bits.
185
187
fn n_up ( self , n : Self :: Int ) -> Self {
186
188
let bits = self . to_bits ( ) ;
187
189
if self . is_nan ( ) || bits == Self :: INFINITY . to_bits ( ) || n == Self :: Int :: ZERO {
@@ -194,16 +196,13 @@ pub trait FloatExt: Float {
194
196
let inf_bits = Self :: INFINITY . to_bits ( ) ;
195
197
let ninf_bits = Self :: NEG_INFINITY . to_bits ( ) ;
196
198
197
- dbg ! ( "up" , self , n, crosses_zero, is_positive, inf_bits) ;
198
-
199
199
let next_bits = if abs == Self :: Int :: ZERO {
200
200
min ( n, inf_bits)
201
201
} else if crosses_zero {
202
- let off = n - abs;
203
- if off > inf_bits { inf_bits } else { off }
202
+ min ( n - abs, inf_bits)
204
203
} else if is_positive {
205
204
// Positive, counting up is more positive but this may overflow
206
- match dbg ! ( bits. checked_add( n) ) {
205
+ match bits. checked_add ( n) {
207
206
Some ( v) if v >= inf_bits => inf_bits,
208
207
Some ( v) => v,
209
208
None => inf_bits,
@@ -215,6 +214,7 @@ pub trait FloatExt: Float {
215
214
Self :: from_bits ( next_bits)
216
215
}
217
216
217
+ /// Decrement by one ULP, saturating at negative infinity.
218
218
fn next_down ( self ) -> Self {
219
219
let bits = self . to_bits ( ) ;
220
220
if self . is_nan ( ) || bits == Self :: NEG_INFINITY . to_bits ( ) {
@@ -235,6 +235,7 @@ pub trait FloatExt: Float {
235
235
Self :: from_bits ( next_bits)
236
236
}
237
237
238
+ /// A faster version of `n_down` when skipping a specified number of bits.
238
239
fn n_down ( self , n : Self :: Int ) -> Self {
239
240
let bits = self . to_bits ( ) ;
240
241
if self . is_nan ( ) || bits == Self :: NEG_INFINITY . to_bits ( ) || n == Self :: Int :: ZERO {
@@ -247,21 +248,16 @@ pub trait FloatExt: Float {
247
248
let inf_bits = Self :: INFINITY . to_bits ( ) ;
248
249
let ninf_bits = Self :: NEG_INFINITY . to_bits ( ) ;
249
250
250
- dbg ! ( "down" , self , n, crosses_zero) ;
251
-
252
251
let next_bits = if abs == Self :: Int :: ZERO {
253
- dbg ! ( min( n, inf_bits) | Self :: SIGN_MASK )
252
+ min ( n, inf_bits) | Self :: SIGN_MASK
254
253
} else if crosses_zero {
255
- // dbg!(n - abs | Self::SIGN_MASK)
256
- let off = n - abs;
257
- let off = if off > inf_bits { inf_bits } else { off } ;
258
- off | Self :: SIGN_MASK
254
+ min ( n - abs, inf_bits) | Self :: SIGN_MASK
259
255
} else if is_positive {
260
256
// Positive, counting down is more negative
261
257
bits - n
262
258
} else {
263
259
// Negative, counting up is more negative but this may overflow
264
- match dbg ! ( bits. checked_add( n) ) {
260
+ match bits. checked_add ( n) {
265
261
Some ( v) if v > ninf_bits => ninf_bits,
266
262
Some ( v) => v,
267
263
None => ninf_bits,
@@ -273,7 +269,6 @@ pub trait FloatExt: Float {
273
269
274
270
#[ cfg( test) ]
275
271
mod tests {
276
-
277
272
use super :: * ;
278
273
use crate :: f8;
279
274
@@ -335,13 +330,11 @@ mod tests {
335
330
let v = f8:: ALL [ i] ;
336
331
337
332
for n in 0 ..( f8:: ALL_LEN - 110 ) {
338
- eprintln ! ( "start" ) ;
339
333
let down = v. n_down ( n as u8 ) . to_bits ( ) ;
340
334
let up = v. n_up ( n as u8 ) . to_bits ( ) ;
341
335
342
336
if let Some ( down_exp_idx) = i. checked_sub ( n) {
343
337
// No overflow
344
-
345
338
let mut expected = f8:: ALL [ down_exp_idx] . to_bits ( ) ;
346
339
if n >= 1 {
347
340
let crossed = & f8:: ALL [ down_exp_idx..=i] ;
@@ -350,16 +343,13 @@ mod tests {
350
343
if crossed. iter ( ) . any ( |f| f8:: eq_repr ( * f, f8:: ZERO ) )
351
344
&& crossed. iter ( ) . any ( |f| f8:: eq_repr ( * f, f8:: NEG_ZERO ) )
352
345
{
346
+ // Saturate to -inf if we are out of values
353
347
match down_exp_idx. checked_sub ( 1 ) {
354
348
Some ( v) => expected = f8:: ALL [ v] . to_bits ( ) ,
355
349
None => expected = f8:: NEG_INFINITY . to_bits ( ) ,
356
350
}
357
-
358
- // down_exp_idx -= 1;
359
351
}
360
352
}
361
- // dbg!(f8::ALL[down_exp_idx], down_exp_idx);
362
-
363
353
assert_eq ! ( down, expected, "{i} {n} n_down({v:#010b})" ) ;
364
354
} else {
365
355
// Overflow to -inf
@@ -368,7 +358,6 @@ mod tests {
368
358
369
359
let mut up_exp_idx = i + n;
370
360
if up_exp_idx < f8:: ALL_LEN {
371
- dbg ! ( up_exp_idx) ;
372
361
// No overflow
373
362
if n >= 1 && up_exp_idx < f8:: ALL_LEN {
374
363
let crossed = & f8:: ALL [ i..=up_exp_idx] ;
@@ -381,7 +370,6 @@ mod tests {
381
370
}
382
371
}
383
372
384
- dbg ! ( up_exp_idx) ;
385
373
let expected = if up_exp_idx >= f8:: ALL_LEN {
386
374
f8:: INFINITY . to_bits ( )
387
375
} else {
@@ -396,9 +384,4 @@ mod tests {
396
384
}
397
385
}
398
386
}
399
-
400
- // #[test]
401
- // fn logspace_basic() {
402
- // let v: Vec<_> = logspace::<f8, domain::Unbounded>(f8::ZERO, f8::ONE, 10).collect();
403
- // }
404
387
}
0 commit comments