@@ -374,6 +374,27 @@ fn format_float_decimal(
374374 format ! ( "{bd:.precision$}" )
375375}
376376
377+ /// Converts a `&BigDecimal` to a scientific-like `X.XX * 10^e`.
378+ /// - The returned `String` contains the digits `XXX`, _without_ the separating
379+ /// `.` (the caller must add that to get a valid scientific format number).
380+ /// - `e` is an integer exponent.
381+ fn bd_to_string_exp_with_prec ( bd : & BigDecimal , precision : u64 ) -> ( String , i64 ) {
382+ // Round bd to precision digits (including the leading digit)
383+ // We call `with_prec` twice as it will produce an extra digit if rounding overflows
384+ // (e.g. 9995.with_prec(3) => 1000 * 10^1, but we want 100 * 10^2).
385+ let bd_round = bd. with_prec ( precision) . with_prec ( precision) ;
386+
387+ // Convert to the form XXX * 10^-p (XXX is precision digit long)
388+ let ( frac, p) = bd_round. as_bigint_and_exponent ( ) ;
389+
390+ let digits = frac. to_str_radix ( 10 ) ;
391+ // If we end up with scientific formatting, we would convert XXX to X.XX:
392+ // that divides by 10^(precision-1), so add that to the exponent.
393+ let exponent = -p + precision as i64 - 1 ;
394+
395+ ( digits, exponent)
396+ }
397+
377398fn format_float_scientific (
378399 bd : & BigDecimal ,
379400 precision : Option < usize > ,
@@ -395,20 +416,8 @@ fn format_float_scientific(
395416 } ;
396417 }
397418
398- // Round bd to (1 + precision) digits (including the leading digit)
399- // We call `with_prec` twice as it will produce an extra digit if rounding overflows
400- // (e.g. 9995.with_prec(3) => 1000 * 10^1, but we want 100 * 10^2).
401- let bd_round = bd
402- . with_prec ( precision as u64 + 1 )
403- . with_prec ( precision as u64 + 1 ) ;
404-
405- // Convert to the form XXX * 10^-e (XXX is 1+precision digit long)
406- let ( frac, e) = bd_round. as_bigint_and_exponent ( ) ;
407-
408- // Scale down "XXX" to "X.XX": that divides by 10^precision, so add that to the exponent.
409- let digits = frac. to_str_radix ( 10 ) ;
419+ let ( digits, exponent) = bd_to_string_exp_with_prec ( bd, precision as u64 + 1 ) ;
410420 let ( first_digit, remaining_digits) = digits. split_at ( 1 ) ;
411- let exponent = -e + precision as i64 ;
412421
413422 let dot =
414423 if !remaining_digits. is_empty ( ) || ( precision == 0 && ForceDecimal :: Yes == force_decimal) {
@@ -445,18 +454,7 @@ fn format_float_shortest(
445454 } ;
446455 }
447456
448- // Round bd to precision digits (including the leading digit)
449- // We call `with_prec` twice as it will produce an extra digit if rounding overflows
450- // (e.g. 9995.with_prec(3) => 1000 * 10^1, but we want 100 * 10^2).
451- let bd_round = bd. with_prec ( precision as u64 ) . with_prec ( precision as u64 ) ;
452-
453- // Convert to the form XXX * 10^-p (XXX is precision digit long)
454- let ( frac, e) = bd_round. as_bigint_and_exponent ( ) ;
455-
456- let digits = frac. to_str_radix ( 10 ) ;
457- // If we end up with scientific formatting, we would convert XXX to X.XX:
458- // that divides by 10^(precision-1), so add that to the exponent.
459- let exponent = -e + precision as i64 - 1 ;
457+ let ( digits, exponent) = bd_to_string_exp_with_prec ( bd, precision as u64 ) ;
460458
461459 if exponent < -4 || exponent >= precision as i64 {
462460 // Scientific-ish notation (with a few differences)
0 commit comments