@@ -2397,79 +2397,100 @@ mod tests {
23972397 check :: < f64 > ( 1e-12 ) ;
23982398 }
23992399
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+ /// ```
24002407 macro_rules! check_integer_decode {
24012408 (
24022409 $func_name: ident,
2403- $T : ty,
2410+ $float_type : ty,
24042411 $tolerance: expr
24052412 ) => {
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+
24082436 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
24142447 ) ;
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) ;
24232448 }
2424- }
2449+ } ;
24252450 }
24262451
24272452 #[ test]
24282453 #[ cfg( any( feature = "std" , feature = "libm" ) ) ]
24292454 fn integer_decode_f32 ( ) {
2430- use core:: f32;
2431-
24322455 check_integer_decode ! ( check, f32 , 1e-6 ) ;
24332456
24342457 for sign in [ 1 , -1 ] {
24352458 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) ;
24372460 check ( sign_f * f32:: MIN_POSITIVE , 0x800000 , -149 , sign) ;
24382461 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) ;
24482471 check ( sign_f * f32:: MAX , 0xffffff , 104 , sign) ;
24492472 }
24502473 }
24512474
24522475 #[ test]
24532476 #[ cfg( any( feature = "std" , feature = "libm" ) ) ]
24542477 fn integer_decode_f64 ( ) {
2455- use core:: f64;
2456-
24572478 check_integer_decode ! ( check, f64 , 1e-6 ) ;
24582479
24592480 for sign in [ 1 , -1 ] {
24602481 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) ;
24622483 check ( sign_f * f64:: MIN_POSITIVE , 0x10000000000000 , -1074 , sign) ;
24632484 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) ;
24732494 check ( sign_f * f64:: MAX , 0x1fffffffffffff , 971 , sign) ;
24742495 }
24752496 }
0 commit comments