@@ -52,6 +52,103 @@ macro_rules! assert_biteq {
52
52
} ;
53
53
}
54
54
55
+ mod const_asserts {
56
+ // Shadow some assert implementations that would otherwise not compile in a const-context.
57
+ // Every macro added here also needs to be added in the `float_test!` macro below.
58
+ macro_rules! assert_eq {
59
+ ( $left: expr, $right: expr $( , ) ?) => {
60
+ std:: assert!( $left == $right)
61
+ } ;
62
+ ( $left: expr, $right: expr, $( $arg: tt) +) => {
63
+ std:: assert!( $left == $right, $( $arg) +)
64
+ } ;
65
+ }
66
+
67
+ pub ( crate ) use assert_eq;
68
+ }
69
+
70
+ /// Generate float tests for all our float types, for compile-time and run-time behavior.
71
+ macro_rules! float_test {
72
+ (
73
+ name: $name: ident,
74
+ attrs: {
75
+ $( const : #[ $( $const_meta: meta) ,+ ] , ) ?
76
+ $( f16: #[ $( $f16_meta: meta) ,+ ] , ) ?
77
+ $( const f16: #[ $( $f16_const_meta: meta) ,+ ] , ) ?
78
+ $( f32 : #[ $( $f32_meta: meta) ,+ ] , ) ?
79
+ $( const f32 : #[ $( $f32_const_meta: meta) ,+ ] , ) ?
80
+ $( f64 : #[ $( $f64_meta: meta) ,+ ] , ) ?
81
+ $( const f64 : #[ $( $f64_const_meta: meta) ,+ ] , ) ?
82
+ $( f128: #[ $( $f128_meta: meta) ,+ ] , ) ?
83
+ $( const f128: #[ $( $f128_const_meta: meta) ,+ ] , ) ?
84
+ } ,
85
+ test<$fty: ident> $test: block
86
+ ) => {
87
+ mod $name {
88
+ #[ test]
89
+ $( $( #[ $f16_meta] ) + ) ?
90
+ fn test_f16( ) {
91
+ type $fty = f16;
92
+ $test
93
+ }
94
+
95
+ #[ test]
96
+ $( $( #[ $f32_meta] ) + ) ?
97
+ fn test_f32( ) {
98
+ type $fty = f32 ;
99
+ $test
100
+ }
101
+
102
+ #[ test]
103
+ $( $( #[ $f64_meta] ) + ) ?
104
+ fn test_f64( ) {
105
+ type $fty = f64 ;
106
+ $test
107
+ }
108
+
109
+ #[ test]
110
+ $( $( #[ $f128_meta] ) + ) ?
111
+ fn test_f128( ) {
112
+ type $fty = f128;
113
+ $test
114
+ }
115
+
116
+ $( $( #[ $const_meta] ) + ) ?
117
+ mod const_ {
118
+ use $crate:: floats:: const_asserts:: assert_eq;
119
+
120
+ #[ test]
121
+ $( $( #[ $f16_const_meta] ) + ) ?
122
+ fn test_f16( ) {
123
+ type $fty = f16;
124
+ const { $test }
125
+ }
126
+
127
+ #[ test]
128
+ $( $( #[ $f32_const_meta] ) + ) ?
129
+ fn test_f32( ) {
130
+ type $fty = f32 ;
131
+ const { $test }
132
+ }
133
+
134
+ #[ test]
135
+ $( $( #[ $f64_const_meta] ) + ) ?
136
+ fn test_f64( ) {
137
+ type $fty = f64 ;
138
+ const { $test }
139
+ }
140
+
141
+ #[ test]
142
+ $( $( #[ $f128_const_meta] ) + ) ?
143
+ fn test_f128( ) {
144
+ type $fty = f128;
145
+ const { $test }
146
+ }
147
+ }
148
+ }
149
+ } ;
150
+ }
151
+
55
152
/// Helper function for testing numeric operations
56
153
pub fn test_num < T > ( ten : T , two : T )
57
154
where
@@ -75,3 +172,437 @@ mod f128;
75
172
mod f16;
76
173
mod f32;
77
174
mod f64;
175
+
176
+ float_test ! {
177
+ name: min,
178
+ attrs: {
179
+ f16: #[ cfg( any( miri, target_has_reliable_f16_math) ) ] ,
180
+ f128: #[ cfg( any( miri, target_has_reliable_f128_math) ) ] ,
181
+ } ,
182
+ test<Float > {
183
+ assert_eq!( ( 0.0 as Float ) . min( 0.0 ) , 0.0 ) ;
184
+ assert!( ( 0.0 as Float ) . min( 0.0 ) . is_sign_positive( ) ) ;
185
+ assert_eq!( ( -0.0 as Float ) . min( -0.0 ) , -0.0 ) ;
186
+ assert!( ( -0.0 as Float ) . min( -0.0 ) . is_sign_negative( ) ) ;
187
+ assert_eq!( ( 9.0 as Float ) . min( 9.0 ) , 9.0 ) ;
188
+ assert_eq!( ( -9.0 as Float ) . min( 0.0 ) , -9.0 ) ;
189
+ assert_eq!( ( 0.0 as Float ) . min( 9.0 ) , 0.0 ) ;
190
+ assert!( ( 0.0 as Float ) . min( 9.0 ) . is_sign_positive( ) ) ;
191
+ assert_eq!( ( -0.0 as Float ) . min( 9.0 ) , -0.0 ) ;
192
+ assert!( ( -0.0 as Float ) . min( 9.0 ) . is_sign_negative( ) ) ;
193
+ assert_eq!( ( -0.0 as Float ) . min( -9.0 ) , -9.0 ) ;
194
+ assert_eq!( Float :: INFINITY . min( 9.0 ) , 9.0 ) ;
195
+ assert_eq!( ( 9.0 as Float ) . min( Float :: INFINITY ) , 9.0 ) ;
196
+ assert_eq!( Float :: INFINITY . min( -9.0 ) , -9.0 ) ;
197
+ assert_eq!( ( -9.0 as Float ) . min( Float :: INFINITY ) , -9.0 ) ;
198
+ assert_eq!( Float :: NEG_INFINITY . min( 9.0 ) , Float :: NEG_INFINITY ) ;
199
+ assert_eq!( ( 9.0 as Float ) . min( Float :: NEG_INFINITY ) , Float :: NEG_INFINITY ) ;
200
+ assert_eq!( Float :: NEG_INFINITY . min( -9.0 ) , Float :: NEG_INFINITY ) ;
201
+ assert_eq!( ( -9.0 as Float ) . min( Float :: NEG_INFINITY ) , Float :: NEG_INFINITY ) ;
202
+ assert_eq!( Float :: NAN . min( 9.0 ) , 9.0 ) ;
203
+ assert_eq!( Float :: NAN . min( -9.0 ) , -9.0 ) ;
204
+ assert_eq!( ( 9.0 as Float ) . min( Float :: NAN ) , 9.0 ) ;
205
+ assert_eq!( ( -9.0 as Float ) . min( Float :: NAN ) , -9.0 ) ;
206
+ assert!( Float :: NAN . min( Float :: NAN ) . is_nan( ) ) ;
207
+ }
208
+ }
209
+
210
+ float_test ! {
211
+ name: max,
212
+ attrs: {
213
+ f16: #[ cfg( any( miri, target_has_reliable_f16_math) ) ] ,
214
+ f128: #[ cfg( any( miri, target_has_reliable_f128_math) ) ] ,
215
+ } ,
216
+ test<Float > {
217
+ assert_eq!( ( 0.0 as Float ) . max( 0.0 ) , 0.0 ) ;
218
+ assert!( ( 0.0 as Float ) . max( 0.0 ) . is_sign_positive( ) ) ;
219
+ assert_eq!( ( -0.0 as Float ) . max( -0.0 ) , -0.0 ) ;
220
+ assert!( ( -0.0 as Float ) . max( -0.0 ) . is_sign_negative( ) ) ;
221
+ assert_eq!( ( 9.0 as Float ) . max( 9.0 ) , 9.0 ) ;
222
+ assert_eq!( ( -9.0 as Float ) . max( 0.0 ) , 0.0 ) ;
223
+ assert!( ( -9.0 as Float ) . max( 0.0 ) . is_sign_positive( ) ) ;
224
+ assert_eq!( ( -9.0 as Float ) . max( -0.0 ) , -0.0 ) ;
225
+ assert!( ( -9.0 as Float ) . max( -0.0 ) . is_sign_negative( ) ) ;
226
+ assert_eq!( ( 0.0 as Float ) . max( 9.0 ) , 9.0 ) ;
227
+ assert_eq!( ( 0.0 as Float ) . max( -9.0 ) , 0.0 ) ;
228
+ assert!( ( 0.0 as Float ) . max( -9.0 ) . is_sign_positive( ) ) ;
229
+ assert_eq!( ( -0.0 as Float ) . max( -9.0 ) , -0.0 ) ;
230
+ assert!( ( -0.0 as Float ) . max( -9.0 ) . is_sign_negative( ) ) ;
231
+ assert_eq!( Float :: INFINITY . max( 9.0 ) , Float :: INFINITY ) ;
232
+ assert_eq!( ( 9.0 as Float ) . max( Float :: INFINITY ) , Float :: INFINITY ) ;
233
+ assert_eq!( Float :: INFINITY . max( -9.0 ) , Float :: INFINITY ) ;
234
+ assert_eq!( ( -9.0 as Float ) . max( Float :: INFINITY ) , Float :: INFINITY ) ;
235
+ assert_eq!( Float :: NEG_INFINITY . max( 9.0 ) , 9.0 ) ;
236
+ assert_eq!( ( 9.0 as Float ) . max( Float :: NEG_INFINITY ) , 9.0 ) ;
237
+ assert_eq!( Float :: NEG_INFINITY . max( -9.0 ) , -9.0 ) ;
238
+ assert_eq!( ( -9.0 as Float ) . max( Float :: NEG_INFINITY ) , -9.0 ) ;
239
+ assert_eq!( Float :: NAN . max( 9.0 ) , 9.0 ) ;
240
+ assert_eq!( Float :: NAN . max( -9.0 ) , -9.0 ) ;
241
+ assert_eq!( ( 9.0 as Float ) . max( Float :: NAN ) , 9.0 ) ;
242
+ assert_eq!( ( -9.0 as Float ) . max( Float :: NAN ) , -9.0 ) ;
243
+ assert!( Float :: NAN . max( Float :: NAN ) . is_nan( ) ) ;
244
+ }
245
+ }
246
+
247
+ float_test ! {
248
+ name: minimum,
249
+ attrs: {
250
+ f16: #[ cfg( any( miri, target_has_reliable_f16_math) ) ] ,
251
+ f128: #[ cfg( any( miri, target_has_reliable_f128_math) ) ] ,
252
+ } ,
253
+ test<Float > {
254
+ assert_eq!( ( 0.0 as Float ) . minimum( 0.0 ) , 0.0 ) ;
255
+ assert!( ( 0.0 as Float ) . minimum( 0.0 ) . is_sign_positive( ) ) ;
256
+ assert_eq!( ( -0.0 as Float ) . minimum( 0.0 ) , -0.0 ) ;
257
+ assert!( ( -0.0 as Float ) . minimum( 0.0 ) . is_sign_negative( ) ) ;
258
+ assert_eq!( ( -0.0 as Float ) . minimum( -0.0 ) , -0.0 ) ;
259
+ assert!( ( -0.0 as Float ) . minimum( -0.0 ) . is_sign_negative( ) ) ;
260
+ assert_eq!( ( 9.0 as Float ) . minimum( 9.0 ) , 9.0 ) ;
261
+ assert_eq!( ( -9.0 as Float ) . minimum( 0.0 ) , -9.0 ) ;
262
+ assert_eq!( ( 0.0 as Float ) . minimum( 9.0 ) , 0.0 ) ;
263
+ assert!( ( 0.0 as Float ) . minimum( 9.0 ) . is_sign_positive( ) ) ;
264
+ assert_eq!( ( -0.0 as Float ) . minimum( 9.0 ) , -0.0 ) ;
265
+ assert!( ( -0.0 as Float ) . minimum( 9.0 ) . is_sign_negative( ) ) ;
266
+ assert_eq!( ( -0.0 as Float ) . minimum( -9.0 ) , -9.0 ) ;
267
+ assert_eq!( Float :: INFINITY . minimum( 9.0 ) , 9.0 ) ;
268
+ assert_eq!( ( 9.0 as Float ) . minimum( Float :: INFINITY ) , 9.0 ) ;
269
+ assert_eq!( Float :: INFINITY . minimum( -9.0 ) , -9.0 ) ;
270
+ assert_eq!( ( -9.0 as Float ) . minimum( Float :: INFINITY ) , -9.0 ) ;
271
+ assert_eq!( Float :: NEG_INFINITY . minimum( 9.0 ) , Float :: NEG_INFINITY ) ;
272
+ assert_eq!( ( 9.0 as Float ) . minimum( Float :: NEG_INFINITY ) , Float :: NEG_INFINITY ) ;
273
+ assert_eq!( Float :: NEG_INFINITY . minimum( -9.0 ) , Float :: NEG_INFINITY ) ;
274
+ assert_eq!( ( -9.0 as Float ) . minimum( Float :: NEG_INFINITY ) , Float :: NEG_INFINITY ) ;
275
+ assert!( Float :: NAN . minimum( 9.0 ) . is_nan( ) ) ;
276
+ assert!( Float :: NAN . minimum( -9.0 ) . is_nan( ) ) ;
277
+ assert!( ( 9.0 as Float ) . minimum( Float :: NAN ) . is_nan( ) ) ;
278
+ assert!( ( -9.0 as Float ) . minimum( Float :: NAN ) . is_nan( ) ) ;
279
+ assert!( Float :: NAN . minimum( Float :: NAN ) . is_nan( ) ) ;
280
+ }
281
+ }
282
+
283
+ float_test ! {
284
+ name: maxium,
285
+ attrs: {
286
+ f16: #[ cfg( any( miri, target_has_reliable_f16_math) ) ] ,
287
+ f128: #[ cfg( any( miri, target_has_reliable_f128_math) ) ] ,
288
+ } ,
289
+ test<Float > {
290
+ assert_eq!( ( 0.0 as Float ) . maximum( 0.0 ) , 0.0 ) ;
291
+ assert!( ( 0.0 as Float ) . maximum( 0.0 ) . is_sign_positive( ) ) ;
292
+ assert_eq!( ( -0.0 as Float ) . maximum( 0.0 ) , 0.0 ) ;
293
+ assert!( ( -0.0 as Float ) . maximum( 0.0 ) . is_sign_positive( ) ) ;
294
+ assert_eq!( ( -0.0 as Float ) . maximum( -0.0 ) , -0.0 ) ;
295
+ assert!( ( -0.0 as Float ) . maximum( -0.0 ) . is_sign_negative( ) ) ;
296
+ assert_eq!( ( 9.0 as Float ) . maximum( 9.0 ) , 9.0 ) ;
297
+ assert_eq!( ( -9.0 as Float ) . maximum( 0.0 ) , 0.0 ) ;
298
+ assert!( ( -9.0 as Float ) . maximum( 0.0 ) . is_sign_positive( ) ) ;
299
+ assert_eq!( ( -9.0 as Float ) . maximum( -0.0 ) , -0.0 ) ;
300
+ assert!( ( -9.0 as Float ) . maximum( -0.0 ) . is_sign_negative( ) ) ;
301
+ assert_eq!( ( 0.0 as Float ) . maximum( 9.0 ) , 9.0 ) ;
302
+ assert_eq!( ( 0.0 as Float ) . maximum( -9.0 ) , 0.0 ) ;
303
+ assert!( ( 0.0 as Float ) . maximum( -9.0 ) . is_sign_positive( ) ) ;
304
+ assert_eq!( ( -0.0 as Float ) . maximum( -9.0 ) , -0.0 ) ;
305
+ assert!( ( -0.0 as Float ) . maximum( -9.0 ) . is_sign_negative( ) ) ;
306
+ assert_eq!( Float :: INFINITY . maximum( 9.0 ) , Float :: INFINITY ) ;
307
+ assert_eq!( ( 9.0 as Float ) . maximum( Float :: INFINITY ) , Float :: INFINITY ) ;
308
+ assert_eq!( Float :: INFINITY . maximum( -9.0 ) , Float :: INFINITY ) ;
309
+ assert_eq!( ( -9.0 as Float ) . maximum( Float :: INFINITY ) , Float :: INFINITY ) ;
310
+ assert_eq!( Float :: NEG_INFINITY . maximum( 9.0 ) , 9.0 ) ;
311
+ assert_eq!( ( 9.0 as Float ) . maximum( Float :: NEG_INFINITY ) , 9.0 ) ;
312
+ assert_eq!( Float :: NEG_INFINITY . maximum( -9.0 ) , -9.0 ) ;
313
+ assert_eq!( ( -9.0 as Float ) . maximum( Float :: NEG_INFINITY ) , -9.0 ) ;
314
+ assert!( Float :: NAN . maximum( 9.0 ) . is_nan( ) ) ;
315
+ assert!( Float :: NAN . maximum( -9.0 ) . is_nan( ) ) ;
316
+ assert!( ( 9.0 as Float ) . maximum( Float :: NAN ) . is_nan( ) ) ;
317
+ assert!( ( -9.0 as Float ) . maximum( Float :: NAN ) . is_nan( ) ) ;
318
+ assert!( Float :: NAN . maximum( Float :: NAN ) . is_nan( ) ) ;
319
+ }
320
+ }
321
+
322
+ float_test ! {
323
+ name: midpoint,
324
+ attrs: {
325
+ f16: #[ cfg( any( miri, target_has_reliable_f16_math) ) ] ,
326
+ f128: #[ cfg( any( miri, target_has_reliable_f128_math) ) ] ,
327
+ } ,
328
+ test<Float > {
329
+ assert_eq!( ( 0.5 as Float ) . midpoint( 0.5 ) , 0.5 ) ;
330
+ assert_eq!( ( 0.5 as Float ) . midpoint( 2.5 ) , 1.5 ) ;
331
+ assert_eq!( ( 3.0 as Float ) . midpoint( 4.0 ) , 3.5 ) ;
332
+ assert_eq!( ( -3.0 as Float ) . midpoint( 4.0 ) , 0.5 ) ;
333
+ assert_eq!( ( 3.0 as Float ) . midpoint( -4.0 ) , -0.5 ) ;
334
+ assert_eq!( ( -3.0 as Float ) . midpoint( -4.0 ) , -3.5 ) ;
335
+ assert_eq!( ( 0.0 as Float ) . midpoint( 0.0 ) , 0.0 ) ;
336
+ assert_eq!( ( -0.0 as Float ) . midpoint( -0.0 ) , -0.0 ) ;
337
+ assert_eq!( ( -5.0 as Float ) . midpoint( 5.0 ) , 0.0 ) ;
338
+ assert_eq!( Float :: MAX . midpoint( Float :: MIN ) , 0.0 ) ;
339
+ assert_eq!( Float :: MIN . midpoint( Float :: MAX ) , -0.0 ) ;
340
+ assert_eq!( Float :: MAX . midpoint( Float :: MIN_POSITIVE ) , Float :: MAX / 2. ) ;
341
+ assert_eq!( ( -Float :: MAX ) . midpoint( Float :: MIN_POSITIVE ) , -Float :: MAX / 2. ) ;
342
+ assert_eq!( Float :: MAX . midpoint( -Float :: MIN_POSITIVE ) , Float :: MAX / 2. ) ;
343
+ assert_eq!( ( -Float :: MAX ) . midpoint( -Float :: MIN_POSITIVE ) , -Float :: MAX / 2. ) ;
344
+ assert_eq!( ( Float :: MIN_POSITIVE ) . midpoint( Float :: MAX ) , Float :: MAX / 2. ) ;
345
+ assert_eq!( ( Float :: MIN_POSITIVE ) . midpoint( -Float :: MAX ) , -Float :: MAX / 2. ) ;
346
+ assert_eq!( ( -Float :: MIN_POSITIVE ) . midpoint( Float :: MAX ) , Float :: MAX / 2. ) ;
347
+ assert_eq!( ( -Float :: MIN_POSITIVE ) . midpoint( -Float :: MAX ) , -Float :: MAX / 2. ) ;
348
+ assert_eq!( Float :: MAX . midpoint( Float :: MAX ) , Float :: MAX ) ;
349
+ assert_eq!(
350
+ ( Float :: MIN_POSITIVE ) . midpoint( Float :: MIN_POSITIVE ) ,
351
+ Float :: MIN_POSITIVE
352
+ ) ;
353
+ assert_eq!(
354
+ ( -Float :: MIN_POSITIVE ) . midpoint( -Float :: MIN_POSITIVE ) ,
355
+ -Float :: MIN_POSITIVE
356
+ ) ;
357
+ assert_eq!( Float :: MAX . midpoint( 5.0 ) , Float :: MAX / 2.0 + 2.5 ) ;
358
+ assert_eq!( Float :: MAX . midpoint( -5.0 ) , Float :: MAX / 2.0 - 2.5 ) ;
359
+ assert_eq!( Float :: INFINITY . midpoint( Float :: INFINITY ) , Float :: INFINITY ) ;
360
+ assert_eq!(
361
+ Float :: NEG_INFINITY . midpoint( Float :: NEG_INFINITY ) ,
362
+ Float :: NEG_INFINITY
363
+ ) ;
364
+ assert!( Float :: NAN . midpoint( 1.0 ) . is_nan( ) ) ;
365
+ assert!( ( 1.0 as Float ) . midpoint( Float :: NAN ) . is_nan( ) ) ;
366
+ assert!( Float :: NAN . midpoint( Float :: NAN ) . is_nan( ) ) ;
367
+ }
368
+ }
369
+
370
+ // Separate test since the `for` loops cannot be run in `const`.
371
+ float_test ! {
372
+ name: midpoint_large_magnitude,
373
+ attrs: {
374
+ const : #[ cfg( false ) ] ,
375
+ f16: #[ cfg( any( miri, target_has_reliable_f16_math) ) ] ,
376
+ f128: #[ cfg( any( miri, target_has_reliable_f128_math) ) ] ,
377
+ } ,
378
+ test<Float > {
379
+ // test if large differences in magnitude are still correctly computed.
380
+ // NOTE: that because of how small x and y are, x + y can never overflow
381
+ // so (x + y) / 2.0 is always correct
382
+ // in particular, `2.pow(i)` will never be at the max exponent, so it could
383
+ // be safely doubled, while j is significantly smaller.
384
+ for i in Float :: MAX_EXP . saturating_sub( 64 ) ..Float :: MAX_EXP {
385
+ for j in 0 ..64u8 {
386
+ let large = ( 2.0 as Float ) . powi( i) ;
387
+ // a much smaller number, such that there is no chance of overflow to test
388
+ // potential double rounding in midpoint's implementation.
389
+ let small = ( 2.0 as Float ) . powi( Float :: MAX_EXP - 1 )
390
+ * Float :: EPSILON
391
+ * Float :: from( j) ;
392
+
393
+ let naive = ( large + small) / 2.0 ;
394
+ let midpoint = large. midpoint( small) ;
395
+
396
+ assert_eq!( naive, midpoint) ;
397
+ }
398
+ }
399
+ }
400
+ }
401
+
402
+ float_test ! {
403
+ name: abs,
404
+ attrs: {
405
+ f16: #[ cfg( any( miri, target_has_reliable_f16_math) ) ] ,
406
+ f128: #[ cfg( any( miri, target_has_reliable_f128_math) ) ] ,
407
+ } ,
408
+ test<Float > {
409
+ assert_eq!( ( -1.0 as Float ) . abs( ) , 1.0 ) ;
410
+ assert_eq!( ( 1.0 as Float ) . abs( ) , 1.0 ) ;
411
+ assert_eq!( Float :: NEG_INFINITY . abs( ) , Float :: INFINITY ) ;
412
+ assert_eq!( Float :: INFINITY . abs( ) , Float :: INFINITY ) ;
413
+ }
414
+ }
415
+
416
+ float_test ! {
417
+ name: copysign,
418
+ attrs: {
419
+ f16: #[ cfg( any( miri, target_has_reliable_f16_math) ) ] ,
420
+ f128: #[ cfg( any( miri, target_has_reliable_f128_math) ) ] ,
421
+ } ,
422
+ test<Float > {
423
+ assert_eq!( ( 1.0 as Float ) . copysign( -2.0 ) , -1.0 ) ;
424
+ assert_eq!( ( -1.0 as Float ) . copysign( 2.0 ) , 1.0 ) ;
425
+ assert_eq!( Float :: INFINITY . copysign( -0.0 ) , Float :: NEG_INFINITY ) ;
426
+ assert_eq!( Float :: NEG_INFINITY . copysign( 0.0 ) , Float :: INFINITY ) ;
427
+ }
428
+ }
429
+
430
+ float_test ! {
431
+ name: rem_euclid,
432
+ attrs: {
433
+ const : #[ cfg( false ) ] ,
434
+ f16: #[ cfg( any( miri, target_has_reliable_f16_math) ) ] ,
435
+ f128: #[ cfg( any( miri, target_has_reliable_f128_math) ) ] ,
436
+ } ,
437
+ test<Float > {
438
+ assert!( Float :: INFINITY . rem_euclid( 42.0 as Float ) . is_nan( ) ) ;
439
+ assert_eq!( ( 42.0 as Float ) . rem_euclid( Float :: INFINITY ) , ( 42.0 as Float ) ) ;
440
+ assert!( ( 42.0 as Float ) . rem_euclid( Float :: NAN ) . is_nan( ) ) ;
441
+ assert!( Float :: INFINITY . rem_euclid( Float :: INFINITY ) . is_nan( ) ) ;
442
+ assert!( Float :: INFINITY . rem_euclid( Float :: NAN ) . is_nan( ) ) ;
443
+ assert!( Float :: NAN . rem_euclid( Float :: INFINITY ) . is_nan( ) ) ;
444
+ }
445
+ }
446
+
447
+ float_test ! {
448
+ name: div_euclid,
449
+ attrs: {
450
+ const : #[ cfg( false ) ] ,
451
+ f16: #[ cfg( any( miri, target_has_reliable_f16_math) ) ] ,
452
+ f128: #[ cfg( any( miri, target_has_reliable_f128_math) ) ] ,
453
+ } ,
454
+ test<Float > {
455
+ assert_eq!( ( 42.0 as Float ) . div_euclid( Float :: INFINITY ) , 0.0 ) ;
456
+ assert!( ( 42.0 as Float ) . div_euclid( Float :: NAN ) . is_nan( ) ) ;
457
+ assert!( Float :: INFINITY . div_euclid( Float :: INFINITY ) . is_nan( ) ) ;
458
+ assert!( Float :: INFINITY . div_euclid( Float :: NAN ) . is_nan( ) ) ;
459
+ assert!( Float :: NAN . div_euclid( Float :: INFINITY ) . is_nan( ) ) ;
460
+ }
461
+ }
462
+
463
+ float_test ! {
464
+ name: floor,
465
+ attrs: {
466
+ f16: #[ cfg( any( miri, target_has_reliable_f16_math) ) ] ,
467
+ f128: #[ cfg( any( miri, target_has_reliable_f128_math) ) ] ,
468
+ } ,
469
+ test<Float > {
470
+ assert_eq!( ( 0.0 as Float ) . floor( ) , 0.0 ) ;
471
+ assert!( ( 0.0 as Float ) . floor( ) . is_sign_positive( ) ) ;
472
+ assert_eq!( ( -0.0 as Float ) . floor( ) , -0.0 ) ;
473
+ assert!( ( -0.0 as Float ) . floor( ) . is_sign_negative( ) ) ;
474
+ assert_eq!( ( 0.5 as Float ) . floor( ) , 0.0 ) ;
475
+ assert_eq!( ( -0.5 as Float ) . floor( ) , -1.0 ) ;
476
+ assert_eq!( ( 1.5 as Float ) . floor( ) , 1.0 ) ;
477
+ assert_eq!( Float :: MAX . floor( ) , Float :: MAX ) ;
478
+ assert_eq!( Float :: MIN . floor( ) , Float :: MIN ) ;
479
+ assert_eq!( Float :: MIN_POSITIVE . floor( ) , 0.0 ) ;
480
+ assert_eq!( ( -Float :: MIN_POSITIVE ) . floor( ) , -1.0 ) ;
481
+ assert!( Float :: NAN . floor( ) . is_nan( ) ) ;
482
+ assert_eq!( Float :: INFINITY . floor( ) , Float :: INFINITY ) ;
483
+ assert_eq!( Float :: NEG_INFINITY . floor( ) , Float :: NEG_INFINITY ) ;
484
+ }
485
+ }
486
+
487
+ float_test ! {
488
+ name: ceil,
489
+ attrs: {
490
+ f16: #[ cfg( any( miri, target_has_reliable_f16_math) ) ] ,
491
+ f128: #[ cfg( any( miri, target_has_reliable_f128_math) ) ] ,
492
+ } ,
493
+ test<Float > {
494
+ assert_eq!( ( 0.0 as Float ) . ceil( ) , 0.0 ) ;
495
+ assert!( ( 0.0 as Float ) . ceil( ) . is_sign_positive( ) ) ;
496
+ assert_eq!( ( -0.0 as Float ) . ceil( ) , 0.0 ) ;
497
+ assert!( ( -0.0 as Float ) . ceil( ) . is_sign_negative( ) ) ;
498
+ assert_eq!( ( 0.5 as Float ) . ceil( ) , 1.0 ) ;
499
+ assert_eq!( ( -0.5 as Float ) . ceil( ) , 0.0 ) ;
500
+ assert_eq!( Float :: MAX . ceil( ) , Float :: MAX ) ;
501
+ assert_eq!( Float :: MIN . ceil( ) , Float :: MIN ) ;
502
+ assert_eq!( Float :: MIN_POSITIVE . ceil( ) , 1.0 ) ;
503
+ assert_eq!( ( -Float :: MIN_POSITIVE ) . ceil( ) , 0.0 ) ;
504
+ assert!( Float :: NAN . ceil( ) . is_nan( ) ) ;
505
+ assert_eq!( Float :: INFINITY . ceil( ) , Float :: INFINITY ) ;
506
+ assert_eq!( Float :: NEG_INFINITY . ceil( ) , Float :: NEG_INFINITY ) ;
507
+ }
508
+ }
509
+
510
+ float_test ! {
511
+ name: round,
512
+ attrs: {
513
+ f16: #[ cfg( any( miri, target_has_reliable_f16_math) ) ] ,
514
+ f128: #[ cfg( any( miri, target_has_reliable_f128_math) ) ] ,
515
+ } ,
516
+ test<Float > {
517
+ assert_eq!( ( 0.0 as Float ) . round( ) , 0.0 ) ;
518
+ assert!( ( 0.0 as Float ) . round( ) . is_sign_positive( ) ) ;
519
+ assert_eq!( ( -0.0 as Float ) . round( ) , -0.0 ) ;
520
+ assert!( ( -0.0 as Float ) . round( ) . is_sign_negative( ) ) ;
521
+ assert_eq!( ( 0.5 as Float ) . round( ) , 1.0 ) ;
522
+ assert_eq!( ( -0.5 as Float ) . round( ) , -1.0 ) ;
523
+ assert_eq!( Float :: MAX . round( ) , Float :: MAX ) ;
524
+ assert_eq!( Float :: MIN . round( ) , Float :: MIN ) ;
525
+ assert_eq!( Float :: MIN_POSITIVE . round( ) , 0.0 ) ;
526
+ assert_eq!( ( -Float :: MIN_POSITIVE ) . round( ) , 0.0 ) ;
527
+ assert!( Float :: NAN . round( ) . is_nan( ) ) ;
528
+ assert_eq!( Float :: INFINITY . round( ) , Float :: INFINITY ) ;
529
+ assert_eq!( Float :: NEG_INFINITY . round( ) , Float :: NEG_INFINITY ) ;
530
+ }
531
+ }
532
+
533
+ float_test ! {
534
+ name: round_ties_even,
535
+ attrs: {
536
+ f16: #[ cfg( any( miri, target_has_reliable_f16_math) ) ] ,
537
+ f128: #[ cfg( any( miri, target_has_reliable_f128_math) ) ] ,
538
+ } ,
539
+ test<Float > {
540
+ assert_eq!( ( 0.0 as Float ) . round_ties_even( ) , 0.0 ) ;
541
+ assert!( ( 0.0 as Float ) . round_ties_even( ) . is_sign_positive( ) ) ;
542
+ assert_eq!( ( -0.0 as Float ) . round_ties_even( ) , -0.0 ) ;
543
+ assert!( ( -0.0 as Float ) . round_ties_even( ) . is_sign_negative( ) ) ;
544
+ assert_eq!( ( 0.5 as Float ) . round_ties_even( ) , 0.0 ) ;
545
+ assert!( ( 0.5 as Float ) . round_ties_even( ) . is_sign_positive( ) ) ;
546
+ assert_eq!( ( -0.5 as Float ) . round_ties_even( ) , -0.0 ) ;
547
+ assert!( ( -0.5 as Float ) . round_ties_even( ) . is_sign_negative( ) ) ;
548
+ assert_eq!( Float :: MAX . round_ties_even( ) , Float :: MAX ) ;
549
+ assert_eq!( Float :: MIN . round_ties_even( ) , Float :: MIN ) ;
550
+ assert_eq!( Float :: MIN_POSITIVE . round_ties_even( ) , 0.0 ) ;
551
+ assert_eq!( ( -Float :: MIN_POSITIVE ) . round_ties_even( ) , 0.0 ) ;
552
+ assert!( Float :: NAN . round_ties_even( ) . is_nan( ) ) ;
553
+ assert_eq!( Float :: INFINITY . round_ties_even( ) , Float :: INFINITY ) ;
554
+ assert_eq!( Float :: NEG_INFINITY . round_ties_even( ) , Float :: NEG_INFINITY ) ;
555
+ }
556
+ }
557
+
558
+ float_test ! {
559
+ name: trunc,
560
+ attrs: {
561
+ f16: #[ cfg( any( miri, target_has_reliable_f16_math) ) ] ,
562
+ f128: #[ cfg( any( miri, target_has_reliable_f128_math) ) ] ,
563
+ } ,
564
+ test<Float > {
565
+ assert_eq!( ( 0.0 as Float ) . trunc( ) , 0.0 ) ;
566
+ assert!( ( 0.0 as Float ) . trunc( ) . is_sign_positive( ) ) ;
567
+ assert_eq!( ( -0.0 as Float ) . trunc( ) , -0.0 ) ;
568
+ assert!( ( -0.0 as Float ) . trunc( ) . is_sign_negative( ) ) ;
569
+ assert_eq!( ( 0.5 as Float ) . trunc( ) , 0.0 ) ;
570
+ assert!( ( 0.5 as Float ) . trunc( ) . is_sign_positive( ) ) ;
571
+ assert_eq!( ( -0.5 as Float ) . trunc( ) , -0.0 ) ;
572
+ assert!( ( -0.5 as Float ) . trunc( ) . is_sign_negative( ) ) ;
573
+ assert_eq!( Float :: MAX . trunc( ) , Float :: MAX ) ;
574
+ assert_eq!( Float :: MIN . trunc( ) , Float :: MIN ) ;
575
+ assert_eq!( Float :: MIN_POSITIVE . trunc( ) , 0.0 ) ;
576
+ assert_eq!( ( -Float :: MIN_POSITIVE ) . trunc( ) , 0.0 ) ;
577
+ assert!( Float :: NAN . trunc( ) . is_nan( ) ) ;
578
+ assert_eq!( Float :: INFINITY . trunc( ) , Float :: INFINITY ) ;
579
+ assert_eq!( Float :: NEG_INFINITY . trunc( ) , Float :: NEG_INFINITY ) ;
580
+ }
581
+ }
582
+
583
+ float_test ! {
584
+ name: fract,
585
+ attrs: {
586
+ f16: #[ cfg( any( miri, target_has_reliable_f16_math) ) ] ,
587
+ f128: #[ cfg( any( miri, target_has_reliable_f128_math) ) ] ,
588
+ } ,
589
+ test<Float > {
590
+ assert_eq!( ( 0.0 as Float ) . fract( ) , 0.0 ) ;
591
+ assert!( ( 0.0 as Float ) . fract( ) . is_sign_positive( ) ) ;
592
+ assert_eq!( ( -0.0 as Float ) . fract( ) , 0.0 ) ;
593
+ assert!( ( -0.0 as Float ) . fract( ) . is_sign_positive( ) ) ;
594
+ assert_eq!( ( 0.5 as Float ) . fract( ) , 0.5 ) ;
595
+ assert!( ( 0.5 as Float ) . fract( ) . is_sign_positive( ) ) ;
596
+ assert_eq!( ( -0.5 as Float ) . fract( ) , -0.5 ) ;
597
+ assert!( ( -0.5 as Float ) . fract( ) . is_sign_negative( ) ) ;
598
+ assert_eq!( Float :: MAX . fract( ) , 0.0 ) ;
599
+ assert_eq!( Float :: MIN . fract( ) , 0.0 ) ;
600
+ assert_eq!( Float :: MIN_POSITIVE . fract( ) , Float :: MIN_POSITIVE ) ;
601
+ assert!( Float :: MIN_POSITIVE . fract( ) . is_sign_positive( ) ) ;
602
+ assert_eq!( ( -Float :: MIN_POSITIVE ) . fract( ) , -Float :: MIN_POSITIVE ) ;
603
+ assert!( ( -Float :: MIN_POSITIVE ) . fract( ) . is_sign_negative( ) ) ;
604
+ assert!( Float :: NAN . fract( ) . is_nan( ) ) ;
605
+ assert!( Float :: INFINITY . fract( ) . is_nan( ) ) ;
606
+ assert!( Float :: NEG_INFINITY . fract( ) . is_nan( ) ) ;
607
+ }
608
+ }
0 commit comments