@@ -539,11 +539,20 @@ fn consider_suffix(
539539 }
540540}
541541
542+ fn is_too_large_to_format ( scaled : i128 , precision : usize ) -> bool {
543+ const MAX_FORMATTED : u128 = 10_000_000_000_000_000_000 ;
544+ let precision_factor = 10_u128 . pow ( precision. min ( 19 ) as u32 ) ;
545+ scaled
546+ . unsigned_abs ( )
547+ . checked_mul ( precision_factor)
548+ . is_none_or ( |v| v >= MAX_FORMATTED )
549+ }
550+
542551fn try_format_exact_int_without_suffix_scaling (
543552 value : ParsedNumber ,
544553 opts : & TransformOptions ,
545554 precision : usize ,
546- ) -> Option < String > {
555+ ) -> Option < Result < String > > {
547556 if opts. to != Unit :: None {
548557 return None ;
549558 }
@@ -557,15 +566,38 @@ fn try_format_exact_int_without_suffix_scaling(
557566
558567 let scaled = integer / to_unit;
559568
560- Some ( if precision == 0 {
569+ if is_too_large_to_format ( scaled, precision) {
570+ let value_sci = format_gnu_scientific ( scaled as f64 ) ;
571+ return Some ( Err ( format ! (
572+ "value/precision too large to be printed: '{value_sci}/{precision}' (consider using --to)"
573+ ) ) ) ;
574+ }
575+
576+ Some ( Ok ( if precision == 0 {
561577 scaled. to_string ( )
562578 } else {
563579 format ! (
564580 "{scaled}{}{}" ,
565581 locale_decimal_separator( ) ,
566582 "0" . repeat( precision)
567583 )
568- } )
584+ } ) )
585+ }
586+
587+ fn format_gnu_scientific ( v : f64 ) -> String {
588+ // 6 significant figures with trimmed trailing zeros and signed exponent
589+ let s = format ! ( "{v:.5e}" ) ;
590+ let Some ( e_pos) = s. find ( 'e' ) else {
591+ return s;
592+ } ;
593+ let ( mantissa, rest) = s. split_at ( e_pos) ;
594+ let exp = & rest[ 1 ..] ;
595+ let mantissa = mantissa. trim_end_matches ( '0' ) . trim_end_matches ( '.' ) ;
596+ if exp. starts_with ( '-' ) {
597+ format ! ( "{mantissa}e{exp}" )
598+ } else {
599+ format ! ( "{mantissa}e+{exp}" )
600+ }
569601}
570602
571603fn transform_to (
@@ -577,7 +609,7 @@ fn transform_to(
577609 is_precision_specified : bool ,
578610) -> Result < String > {
579611 if let Some ( result) = try_format_exact_int_without_suffix_scaling ( s, opts, precision) {
580- return Ok ( result) ;
612+ return result;
581613 }
582614
583615 let s = s. to_f64 ( ) ;
0 commit comments