@@ -2397,79 +2397,100 @@ mod tests {
2397
2397
check :: < f64 > ( 1e-12 ) ;
2398
2398
}
2399
2399
2400
+ /// Create a function to test `Float::integer_decode` for a given float type (`f32` or `f64`) and tolerance.
2401
+ ///
2402
+ /// # Examples
2403
+ /// ```rs
2404
+ /// check_integer_decode!(check, f32, 1e-6);
2405
+ /// check(sign_f * 0.0_f32, 0x000000, -150, sign);
2406
+ /// ```
2400
2407
macro_rules! check_integer_decode {
2401
2408
(
2402
2409
$func_name: ident,
2403
- $T : ty,
2410
+ $float_type : ty,
2404
2411
$tolerance: expr
2405
2412
) => {
2406
- fn $func_name( x: $T, x_mantissa: u64 , x_exponent: i16 , x_sign: i8 ) {
2407
- let ( mantissa, exponent, sign) = crate :: float:: Float :: integer_decode( x) ;
2413
+ /// Test the behavior of `Float::integer_decode(input)`
2414
+ fn $func_name( input: $float_type, mantissa: u64 , exponent: i16 , sign: i8 ) {
2415
+ let output = crate :: float:: Float :: integer_decode( input) ;
2416
+
2417
+ assert!(
2418
+ ( mantissa, exponent, sign) == output,
2419
+ "unexpected output of `Float::integer_decode({0:e})`
2420
+ \t expected: {1}
2421
+ \t found: {2}",
2422
+ input,
2423
+ std:: format!( "({:#x} {} {})" , mantissa, exponent, sign) ,
2424
+ std:: format!( "({:#x} {} {})" , output. 0 , output. 1 , output. 2 ) ,
2425
+ ) ;
2426
+
2427
+ // Destructure output and values cast as float
2428
+ let mantissa_f = output. 0 as $float_type;
2429
+ let exponent_f = output. 1 as $float_type;
2430
+ let sign_f = output. 2 as $float_type;
2431
+
2432
+ // Recover input using equation: sign * mantissa * 2^exponent
2433
+ let recovered_input = sign_f * mantissa_f * exponent_f. exp2( ) ;
2434
+ let deviation = recovered_input - input;
2435
+
2408
2436
assert!(
2409
- ( x_mantissa, x_exponent, x_sign) == ( mantissa, exponent, sign) ,
2410
- "{}\n \t {}\n \t {}" ,
2411
- std:: format!( "while testing return value of Float::integer_decode({})" , x) ,
2412
- std:: format!( "expected: ({:#x} {} {})" , x_mantissa, x_exponent, x_sign) ,
2413
- std:: format!( " found: ({:#x} {} {})" , mantissa, exponent, sign) ,
2437
+ deviation. abs( ) < $tolerance,
2438
+ "failed to recover input of `Float::integer_decode({0:e})`
2439
+ \t expected: ~ {:e}
2440
+ \t found: {:e}
2441
+ \t deviation: {:+e}
2442
+ \t tolerance: < {:e}",
2443
+ input,
2444
+ recovered_input,
2445
+ deviation,
2446
+ $tolerance
2414
2447
) ;
2415
-
2416
- let sign_f = sign as $T;
2417
- let mantissa_f = mantissa as $T;
2418
- let exponent_f = exponent as $T;
2419
-
2420
- let abs_difference = ( sign_f * mantissa_f * exponent_f. exp2( ) - x) . abs( ) ;
2421
-
2422
- assert!( abs_difference < $tolerance, "absolute difference {} must be less than {}" , abs_difference, $tolerance) ;
2423
2448
}
2424
- }
2449
+ } ;
2425
2450
}
2426
2451
2427
2452
#[ test]
2428
2453
#[ cfg( any( feature = "std" , feature = "libm" ) ) ]
2429
2454
fn integer_decode_f32 ( ) {
2430
- use core:: f32;
2431
-
2432
2455
check_integer_decode ! ( check, f32 , 1e-6 ) ;
2433
2456
2434
2457
for sign in [ 1 , -1 ] {
2435
2458
let sign_f = sign as f32 ;
2436
- check ( sign_f * 0.0_f32 , 0x000000 , -150 , sign) ;
2459
+ check ( sign_f * 0.0__f32 , 0x000000 , -150 , sign) ;
2437
2460
check ( sign_f * f32:: MIN_POSITIVE , 0x800000 , -149 , sign) ;
2438
2461
check ( sign_f * 0.25_f32 , 0x800000 , -25 , sign) ;
2439
- check ( sign_f * 0.5_f32 , 0x800000 , -24 , sign) ;
2440
- check ( sign_f * 1_f32 , 0x800000 , -23 , sign) ;
2441
- check ( sign_f * 1.5_f32 , 0xc00000 , -23 , sign) ;
2442
- check ( sign_f * 2_f32 , 0x800000 , -22 , sign) ;
2443
- check ( sign_f * 2.5_f32 , 0xa00000 , -22 , sign) ;
2444
- check ( sign_f * 3_f32 , 0xc00000 , -22 , sign) ;
2445
- check ( sign_f * 4_f32 , 0x800000 , -21 , sign) ;
2446
- check ( sign_f * 5_f32 , 0xa00000 , -21 , sign) ;
2447
- check ( sign_f * 42_f32 , 0xa80000 , -18 , sign) ;
2462
+ check ( sign_f * 0.5__f32 , 0x800000 , -24 , sign) ;
2463
+ check ( sign_f * 1____f32 , 0x800000 , -23 , sign) ;
2464
+ check ( sign_f * 1.5__f32 , 0xc00000 , -23 , sign) ;
2465
+ check ( sign_f * 2____f32 , 0x800000 , -22 , sign) ;
2466
+ check ( sign_f * 2.5__f32 , 0xa00000 , -22 , sign) ;
2467
+ check ( sign_f * 3____f32 , 0xc00000 , -22 , sign) ;
2468
+ check ( sign_f * 4____f32 , 0x800000 , -21 , sign) ;
2469
+ check ( sign_f * 5____f32 , 0xa00000 , -21 , sign) ;
2470
+ check ( sign_f * 42___f32 , 0xa80000 , -18 , sign) ;
2448
2471
check ( sign_f * f32:: MAX , 0xffffff , 104 , sign) ;
2449
2472
}
2450
2473
}
2451
2474
2452
2475
#[ test]
2453
2476
#[ cfg( any( feature = "std" , feature = "libm" ) ) ]
2454
2477
fn integer_decode_f64 ( ) {
2455
- use core:: f64;
2456
-
2457
2478
check_integer_decode ! ( check, f64 , 1e-6 ) ;
2458
2479
2459
2480
for sign in [ 1 , -1 ] {
2460
2481
let sign_f = sign as f64 ;
2461
- check ( sign_f * 0.0_f64 , 0x00000000000000 , -1075 , sign) ;
2482
+ check ( sign_f * 0.0__f64 , 0x00000000000000 , -1075 , sign) ;
2462
2483
check ( sign_f * f64:: MIN_POSITIVE , 0x10000000000000 , -1074 , sign) ;
2463
2484
check ( sign_f * 0.25_f64 , 0x10000000000000 , -54 , sign) ;
2464
- check ( sign_f * 0.5_f64 , 0x10000000000000 , -53 , sign) ;
2465
- check ( sign_f * 1_f64 , 0x10000000000000 , -52 , sign) ;
2466
- check ( sign_f * 1.5_f64 , 0x18000000000000 , -52 , sign) ;
2467
- check ( sign_f * 2_f64 , 0x10000000000000 , -51 , sign) ;
2468
- check ( sign_f * 2.5_f64 , 0x14000000000000 , -51 , sign) ;
2469
- check ( sign_f * 3_f64 , 0x18000000000000 , -51 , sign) ;
2470
- check ( sign_f * 4_f64 , 0x10000000000000 , -50 , sign) ;
2471
- check ( sign_f * 5_f64 , 0x14000000000000 , -50 , sign) ;
2472
- check ( sign_f * 42_f64 , 0x15000000000000 , -47 , sign) ;
2485
+ check ( sign_f * 0.5__f64 , 0x10000000000000 , -53 , sign) ;
2486
+ check ( sign_f * 1____f64 , 0x10000000000000 , -52 , sign) ;
2487
+ check ( sign_f * 1.5__f64 , 0x18000000000000 , -52 , sign) ;
2488
+ check ( sign_f * 2____f64 , 0x10000000000000 , -51 , sign) ;
2489
+ check ( sign_f * 2.5__f64 , 0x14000000000000 , -51 , sign) ;
2490
+ check ( sign_f * 3____f64 , 0x18000000000000 , -51 , sign) ;
2491
+ check ( sign_f * 4____f64 , 0x10000000000000 , -50 , sign) ;
2492
+ check ( sign_f * 5____f64 , 0x14000000000000 , -50 , sign) ;
2493
+ check ( sign_f * 42___f64 , 0x15000000000000 , -47 , sign) ;
2473
2494
check ( sign_f * f64:: MAX , 0x1fffffffffffff , 971 , sign) ;
2474
2495
}
2475
2496
}
0 commit comments