@@ -85,7 +85,7 @@ impl Formatter for SignedInt {
8585 x. abs ( ) . to_string ( )
8686 } ;
8787
88- let sign_indicator = get_sign_indicator ( self . positive_sign , & x ) ;
88+ let sign_indicator = get_sign_indicator ( self . positive_sign , x . is_negative ( ) ) ;
8989
9090 write_output ( writer, sign_indicator, s, self . width , self . alignment )
9191 }
@@ -239,8 +239,9 @@ impl Default for Float {
239239impl Formatter for Float {
240240 type Input = f64 ;
241241
242- fn fmt ( & self , writer : impl Write , x : Self :: Input ) -> std:: io:: Result < ( ) > {
243- let mut s = if x. is_finite ( ) {
242+ fn fmt ( & self , writer : impl Write , f : Self :: Input ) -> std:: io:: Result < ( ) > {
243+ let x = f. abs ( ) ;
244+ let s = if x. is_finite ( ) {
244245 match self . variant {
245246 FloatVariant :: Decimal => {
246247 format_float_decimal ( x, self . precision , self . force_decimal )
@@ -259,11 +260,7 @@ impl Formatter for Float {
259260 format_float_non_finite ( x, self . case )
260261 } ;
261262
262- // The format function will parse `x` together with its sign char,
263- // which should be placed in `sign_indicator`. So drop it here
264- s = if x < 0. { s[ 1 ..] . to_string ( ) } else { s } ;
265-
266- let sign_indicator = get_sign_indicator ( self . positive_sign , & x) ;
263+ let sign_indicator = get_sign_indicator ( self . positive_sign , f. is_sign_negative ( ) ) ;
267264
268265 write_output ( writer, sign_indicator, s, self . width , self . alignment )
269266 }
@@ -309,8 +306,8 @@ impl Formatter for Float {
309306 }
310307}
311308
312- fn get_sign_indicator < T : PartialOrd + Default > ( sign : PositiveSign , x : & T ) -> String {
313- if * x >= T :: default ( ) {
309+ fn get_sign_indicator ( sign : PositiveSign , negative : bool ) -> String {
310+ if !negative {
314311 match sign {
315312 PositiveSign :: None => String :: new ( ) ,
316313 PositiveSign :: Plus => String :: from ( "+" ) ,
@@ -324,13 +321,15 @@ fn get_sign_indicator<T: PartialOrd + Default>(sign: PositiveSign, x: &T) -> Str
324321fn format_float_non_finite ( f : f64 , case : Case ) -> String {
325322 debug_assert ! ( !f. is_finite( ) ) ;
326323 let mut s = format ! ( "{f}" ) ;
327- if case == Case :: Uppercase {
328- s. make_ascii_uppercase ( ) ;
324+ match case {
325+ Case :: Lowercase => s. make_ascii_lowercase ( ) , // Forces NaN back to nan.
326+ Case :: Uppercase => s. make_ascii_uppercase ( ) ,
329327 }
330328 s
331329}
332330
333331fn format_float_decimal ( f : f64 , precision : usize , force_decimal : ForceDecimal ) -> String {
332+ debug_assert ! ( !f. is_sign_negative( ) ) ;
334333 if precision == 0 && force_decimal == ForceDecimal :: Yes {
335334 format ! ( "{f:.0}." )
336335 } else {
@@ -344,6 +343,7 @@ fn format_float_scientific(
344343 case : Case ,
345344 force_decimal : ForceDecimal ,
346345) -> String {
346+ debug_assert ! ( !f. is_sign_negative( ) ) ;
347347 let exp_char = match case {
348348 Case :: Lowercase => 'e' ,
349349 Case :: Uppercase => 'E' ,
@@ -383,6 +383,7 @@ fn format_float_shortest(
383383 case : Case ,
384384 force_decimal : ForceDecimal ,
385385) -> String {
386+ debug_assert ! ( !f. is_sign_negative( ) ) ;
386387 // Precision here is about how many digits should be displayed
387388 // instead of how many digits for the fractional part, this means that if
388389 // we pass this to rust's format string, it's always gonna be one less.
@@ -459,21 +460,21 @@ fn format_float_hexadecimal(
459460 case : Case ,
460461 force_decimal : ForceDecimal ,
461462) -> String {
462- let ( sign, first_digit, mantissa, exponent) = if f == 0.0 {
463- ( "" , 0 , 0 , 0 )
463+ debug_assert ! ( !f. is_sign_negative( ) ) ;
464+ let ( first_digit, mantissa, exponent) = if f == 0.0 {
465+ ( 0 , 0 , 0 )
464466 } else {
465467 let bits = f. to_bits ( ) ;
466- let sign = if ( bits >> 63 ) == 1 { "-" } else { "" } ;
467468 let exponent_bits = ( ( bits >> 52 ) & 0x7ff ) as i64 ;
468469 let exponent = exponent_bits - 1023 ;
469470 let mantissa = bits & 0xf_ffff_ffff_ffff ;
470- ( sign , 1 , mantissa, exponent)
471+ ( 1 , mantissa, exponent)
471472 } ;
472473
473474 let mut s = match ( precision, force_decimal) {
474- ( 0 , ForceDecimal :: No ) => format ! ( "{sign} 0x{first_digit}p{exponent:+}" ) ,
475- ( 0 , ForceDecimal :: Yes ) => format ! ( "{sign} 0x{first_digit}.p{exponent:+}" ) ,
476- _ => format ! ( "{sign} 0x{first_digit}.{mantissa:0>13x}p{exponent:+}" ) ,
475+ ( 0 , ForceDecimal :: No ) => format ! ( "0x{first_digit}p{exponent:+}" ) ,
476+ ( 0 , ForceDecimal :: Yes ) => format ! ( "0x{first_digit}.p{exponent:+}" ) ,
477+ _ => format ! ( "0x{first_digit}.{mantissa:0>13x}p{exponent:+}" ) ,
477478 } ;
478479
479480 if case == Case :: Uppercase {
@@ -550,6 +551,18 @@ mod test {
550551 assert_eq ! ( f( 8 ) , "010" ) ;
551552 }
552553
554+ #[ test]
555+ fn non_finite_float ( ) {
556+ use super :: format_float_non_finite;
557+ let f = |x| format_float_non_finite ( x, Case :: Lowercase ) ;
558+ assert_eq ! ( f( f64 :: NAN ) , "nan" ) ;
559+ assert_eq ! ( f( f64 :: INFINITY ) , "inf" ) ;
560+
561+ let f = |x| format_float_non_finite ( x, Case :: Uppercase ) ;
562+ assert_eq ! ( f( f64 :: NAN ) , "NAN" ) ;
563+ assert_eq ! ( f( f64 :: INFINITY ) , "INF" ) ;
564+ }
565+
553566 #[ test]
554567 fn decimal_float ( ) {
555568 use super :: format_float_decimal;
@@ -662,22 +675,14 @@ mod test {
662675 assert_eq ! ( f( 0.125 ) , "0x1.0000000000000p-3" ) ;
663676 assert_eq ! ( f( 256.0 ) , "0x1.0000000000000p+8" ) ;
664677 assert_eq ! ( f( 65536.0 ) , "0x1.0000000000000p+16" ) ;
665- assert_eq ! ( f( -0.00001 ) , "-0x1.4f8b588e368f1p-17" ) ;
666- assert_eq ! ( f( -0.125 ) , "-0x1.0000000000000p-3" ) ;
667- assert_eq ! ( f( -256.0 ) , "-0x1.0000000000000p+8" ) ;
668- assert_eq ! ( f( -65536.0 ) , "-0x1.0000000000000p+16" ) ;
669678
670679 let f = |x| format_float_hexadecimal ( x, 0 , Case :: Lowercase , ForceDecimal :: No ) ;
671680 assert_eq ! ( f( 0.125 ) , "0x1p-3" ) ;
672681 assert_eq ! ( f( 256.0 ) , "0x1p+8" ) ;
673- assert_eq ! ( f( -0.125 ) , "-0x1p-3" ) ;
674- assert_eq ! ( f( -256.0 ) , "-0x1p+8" ) ;
675682
676683 let f = |x| format_float_hexadecimal ( x, 0 , Case :: Lowercase , ForceDecimal :: Yes ) ;
677684 assert_eq ! ( f( 0.125 ) , "0x1.p-3" ) ;
678685 assert_eq ! ( f( 256.0 ) , "0x1.p+8" ) ;
679- assert_eq ! ( f( -0.125 ) , "-0x1.p-3" ) ;
680- assert_eq ! ( f( -256.0 ) , "-0x1.p+8" ) ;
681686 }
682687
683688 #[ test]
@@ -703,11 +708,6 @@ mod test {
703708 assert_eq ! ( f( 0.001171875 ) , "0.00117187" ) ;
704709 assert_eq ! ( f( 0.0001171875 ) , "0.000117187" ) ;
705710 assert_eq ! ( f( 0.001171875001 ) , "0.00117188" ) ;
706- assert_eq ! ( f( -0.1171875 ) , "-0.117188" ) ;
707- assert_eq ! ( f( -0.01171875 ) , "-0.0117188" ) ;
708- assert_eq ! ( f( -0.001171875 ) , "-0.00117187" ) ;
709- assert_eq ! ( f( -0.0001171875 ) , "-0.000117187" ) ;
710- assert_eq ! ( f( -0.001171875001 ) , "-0.00117188" ) ;
711711 }
712712
713713 #[ test]
@@ -718,9 +718,5 @@ mod test {
718718 assert_eq ! ( f( 0.0001 ) , "0.0001" ) ;
719719 assert_eq ! ( f( 0.00001 ) , "1e-05" ) ;
720720 assert_eq ! ( f( 0.000001 ) , "1e-06" ) ;
721- assert_eq ! ( f( -0.001 ) , "-0.001" ) ;
722- assert_eq ! ( f( -0.0001 ) , "-0.0001" ) ;
723- assert_eq ! ( f( -0.00001 ) , "-1e-05" ) ;
724- assert_eq ! ( f( -0.000001 ) , "-1e-06" ) ;
725721 }
726722}
0 commit comments