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