@ -337,6 +337,11 @@ fn format_float(bits: u64, w: u8, t: u8, f: &mut Formatter) -> fmt::Result {
write ! ( f , "0x0.{0:01$x}p{2}" , left_t_bits , digits as usize , emin )
}
} else if e_bits = = max_e_bits {
// Always print a `+` or `-` sign for these special values.
// This makes them easier to parse as they can't be confused as identifiers.
if sign_bit = = 0 {
write ! ( f , "+" ) ? ;
}
if t_bits = = 0 {
// Infinity.
write ! ( f , "Inf" )
@ -375,6 +380,8 @@ fn parse_float(s: &str, w: u8, t: u8) -> Result<u64, &'static str> {
let ( sign_bit , s2 ) = if s . starts_with ( '-' ) {
( 1 u64 < < t + w , & s [ 1 . . ] )
} else if s . starts_with ( '+' ) {
( 0 , & s [ 1 . . ] )
} else {
( 0 , s )
} ;
@ -731,27 +738,29 @@ mod tests {
"0x0.800000p-126" ) ;
assert_eq ! ( Ieee32 ::new ( f32 ::MIN_POSITIVE * f32 ::EPSILON ) . to_string ( ) ,
"0x0.000002p-126" ) ;
assert_eq ! ( Ieee32 ::new ( f32 ::INFINITY ) . to_string ( ) , "Inf" ) ;
assert_eq ! ( Ieee32 ::new ( f32 ::INFINITY ) . to_string ( ) , "+ Inf" ) ;
assert_eq ! ( Ieee32 ::new ( f32 ::NEG_INFINITY ) . to_string ( ) , "-Inf" ) ;
assert_eq ! ( Ieee32 ::new ( f32 ::NAN ) . to_string ( ) , "NaN" ) ;
assert_eq ! ( Ieee32 ::new ( f32 ::NAN ) . to_string ( ) , "+ NaN" ) ;
assert_eq ! ( Ieee32 ::new ( - f32 ::NAN ) . to_string ( ) , "-NaN" ) ;
// Construct some qNaNs with payloads.
assert_eq ! ( Ieee32 ::from_bits ( 0x7fc00001 ) . to_string ( ) , "NaN:0x1" ) ;
assert_eq ! ( Ieee32 ::from_bits ( 0x7ff00001 ) . to_string ( ) , "NaN:0x300001" ) ;
assert_eq ! ( Ieee32 ::from_bits ( 0x7fc00001 ) . to_string ( ) , "+ NaN:0x1" ) ;
assert_eq ! ( Ieee32 ::from_bits ( 0x7ff00001 ) . to_string ( ) , "+ NaN:0x300001" ) ;
// Signaling NaNs.
assert_eq ! ( Ieee32 ::from_bits ( 0x7f800001 ) . to_string ( ) , "sNaN:0x1" ) ;
assert_eq ! ( Ieee32 ::from_bits ( 0x7fa00001 ) . to_string ( ) , "sNaN:0x200001" ) ;
assert_eq ! ( Ieee32 ::from_bits ( 0x7f800001 ) . to_string ( ) , "+ sNaN:0x1" ) ;
assert_eq ! ( Ieee32 ::from_bits ( 0x7fa00001 ) . to_string ( ) , "+ sNaN:0x200001" ) ;
}
#[ test ]
fn parse_ieee32 ( ) {
parse_ok ::< Ieee32 > ( "0.0" , "0.0" ) ;
parse_ok ::< Ieee32 > ( "+0.0" , "0.0" ) ;
parse_ok ::< Ieee32 > ( "-0.0" , "-0.0" ) ;
parse_ok ::< Ieee32 > ( "0x0" , "0.0" ) ;
parse_ok ::< Ieee32 > ( "0x0.0" , "0.0" ) ;
parse_ok ::< Ieee32 > ( "0x.0" , "0.0" ) ;
parse_ok ::< Ieee32 > ( "0x0." , "0.0" ) ;
parse_ok ::< Ieee32 > ( "0x1" , "0x1.000000p0" ) ;
parse_ok ::< Ieee32 > ( "+0x1" , "0x1.000000p0" ) ;
parse_ok ::< Ieee32 > ( "-0x1" , "-0x1.000000p0" ) ;
parse_ok ::< Ieee32 > ( "0x10" , "0x1.000000p4" ) ;
parse_ok ::< Ieee32 > ( "0x10.0" , "0x1.000000p4" ) ;
@ -793,20 +802,22 @@ mod tests {
parse_err ::< Ieee32 > ( "0x1.0p-150" , "Magnitude too small" ) ;
// NaNs and Infs.
parse_ok ::< Ieee32 > ( "Inf" , "Inf" ) ;
parse_ok ::< Ieee32 > ( "Inf" , "+Inf" ) ;
parse_ok ::< Ieee32 > ( "+Inf" , "+Inf" ) ;
parse_ok ::< Ieee32 > ( "-Inf" , "-Inf" ) ;
parse_ok ::< Ieee32 > ( "NaN" , "NaN" ) ;
parse_ok ::< Ieee32 > ( "NaN" , "+NaN" ) ;
parse_ok ::< Ieee32 > ( "+NaN" , "+NaN" ) ;
parse_ok ::< Ieee32 > ( "-NaN" , "-NaN" ) ;
parse_ok ::< Ieee32 > ( "NaN:0x0" , "NaN" ) ;
parse_ok ::< Ieee32 > ( "NaN:0x0" , "+ NaN" ) ;
parse_err ::< Ieee32 > ( "NaN:" , "Float must be hexadecimal" ) ;
parse_err ::< Ieee32 > ( "NaN:0" , "Float must be hexadecimal" ) ;
parse_err ::< Ieee32 > ( "NaN:0x" , "Invalid NaN payload" ) ;
parse_ok ::< Ieee32 > ( "NaN:0x000001" , "NaN:0x1" ) ;
parse_ok ::< Ieee32 > ( "NaN:0x300001" , "NaN:0x300001" ) ;
parse_ok ::< Ieee32 > ( "NaN:0x000001" , "+ NaN:0x1" ) ;
parse_ok ::< Ieee32 > ( "NaN:0x300001" , "+ NaN:0x300001" ) ;
parse_err ::< Ieee32 > ( "NaN:0x400001" , "Invalid NaN payload" ) ;
parse_ok ::< Ieee32 > ( "sNaN:0x1" , "sNaN:0x1" ) ;
parse_ok ::< Ieee32 > ( "sNaN:0x1" , "+ sNaN:0x1" ) ;
parse_err ::< Ieee32 > ( "sNaN:0x0" , "Invalid sNaN payload" ) ;
parse_ok ::< Ieee32 > ( "sNaN:0x200001" , "sNaN:0x200001" ) ;
parse_ok ::< Ieee32 > ( "sNaN:0x200001" , "+ sNaN:0x200001" ) ;
parse_err ::< Ieee32 > ( "sNaN:0x400001" , "Invalid sNaN payload" ) ;
}
@ -829,19 +840,20 @@ mod tests {
"0x0.8000000000000p-1022" ) ;
assert_eq ! ( Ieee64 ::new ( f64 ::MIN_POSITIVE * f64 ::EPSILON ) . to_string ( ) ,
"0x0.0000000000001p-1022" ) ;
assert_eq ! ( Ieee64 ::new ( f64 ::INFINITY ) . to_string ( ) , "Inf" ) ;
assert_eq ! ( Ieee64 ::new ( f64 ::INFINITY ) . to_string ( ) , "+ Inf" ) ;
assert_eq ! ( Ieee64 ::new ( f64 ::NEG_INFINITY ) . to_string ( ) , "-Inf" ) ;
assert_eq ! ( Ieee64 ::new ( f64 ::NAN ) . to_string ( ) , "NaN" ) ;
assert_eq ! ( Ieee64 ::new ( f64 ::NAN ) . to_string ( ) , "+ NaN" ) ;
assert_eq ! ( Ieee64 ::new ( - f64 ::NAN ) . to_string ( ) , "-NaN" ) ;
// Construct some qNaNs with payloads.
assert_eq ! ( Ieee64 ::from_bits ( 0x7ff8000000000001 ) . to_string ( ) , "NaN:0x1" ) ;
assert_eq ! ( Ieee64 ::from_bits ( 0x7ff8000000000001 ) . to_string ( ) ,
"+NaN:0x1" ) ;
assert_eq ! ( Ieee64 ::from_bits ( 0x7ffc000000000001 ) . to_string ( ) ,
"NaN:0x4000000000001" ) ;
"+ NaN:0x4000000000001" ) ;
// Signaling NaNs.
assert_eq ! ( Ieee64 ::from_bits ( 0x7ff0000000000001 ) . to_string ( ) ,
"sNaN:0x1" ) ;
"+ sNaN:0x1" ) ;
assert_eq ! ( Ieee64 ::from_bits ( 0x7ff4000000000001 ) . to_string ( ) ,
"sNaN:0x4000000000001" ) ;
"+ sNaN:0x4000000000001" ) ;
}
#[ test ]
@ -894,20 +906,20 @@ mod tests {
parse_err ::< Ieee64 > ( "0x1.0p-1075" , "Magnitude too small" ) ;
// NaNs and Infs.
parse_ok ::< Ieee64 > ( "Inf" , "Inf" ) ;
parse_ok ::< Ieee64 > ( "Inf" , "+ Inf" ) ;
parse_ok ::< Ieee64 > ( "-Inf" , "-Inf" ) ;
parse_ok ::< Ieee64 > ( "NaN" , "NaN" ) ;
parse_ok ::< Ieee64 > ( "NaN" , "+ NaN" ) ;
parse_ok ::< Ieee64 > ( "-NaN" , "-NaN" ) ;
parse_ok ::< Ieee64 > ( "NaN:0x0" , "NaN" ) ;
parse_ok ::< Ieee64 > ( "NaN:0x0" , "+ NaN" ) ;
parse_err ::< Ieee64 > ( "NaN:" , "Float must be hexadecimal" ) ;
parse_err ::< Ieee64 > ( "NaN:0" , "Float must be hexadecimal" ) ;
parse_err ::< Ieee64 > ( "NaN:0x" , "Invalid NaN payload" ) ;
parse_ok ::< Ieee64 > ( "NaN:0x000001" , "NaN:0x1" ) ;
parse_ok ::< Ieee64 > ( "NaN:0x4000000000001" , "NaN:0x4000000000001" ) ;
parse_ok ::< Ieee64 > ( "NaN:0x000001" , "+ NaN:0x1" ) ;
parse_ok ::< Ieee64 > ( "NaN:0x4000000000001" , "+ NaN:0x4000000000001" ) ;
parse_err ::< Ieee64 > ( "NaN:0x8000000000001" , "Invalid NaN payload" ) ;
parse_ok ::< Ieee64 > ( "sNaN:0x1" , "sNaN:0x1" ) ;
parse_ok ::< Ieee64 > ( "sNaN:0x1" , "+ sNaN:0x1" ) ;
parse_err ::< Ieee64 > ( "sNaN:0x0" , "Invalid sNaN payload" ) ;
parse_ok ::< Ieee64 > ( "sNaN:0x4000000000001" , "sNaN:0x4000000000001" ) ;
parse_ok ::< Ieee64 > ( "sNaN:0x4000000000001" , "+ sNaN:0x4000000000001" ) ;
parse_err ::< Ieee64 > ( "sNaN:0x8000000000001" , "Invalid sNaN payload" ) ;
}
}