@@ -1671,16 +1671,15 @@ auto write_big(double value, int precision, char* out, size_t n,
16711671 writer w = {out, out + n};
16721672 if (traits::is_negative (bits)) w.write (' -' );
16731673
1674- char digits[805 ]; // num < 2**2668 has <= 804 digits, plus a carry digit .
1674+ char digits[805 ]; // num < 2**2668 has at most 804 digits, plus a carry.
16751675 digits[0 ] = ' 0' ;
16761676 char * p = digits;
1677- int num_digits = 1 ; // significant digits to emit (>= 1)
1678- int lead_exp = 0 ; // exponent of the leading digit
1677+ int num_digits = 1 ;
1678+ int lead_exp = 0 ; // exponent of the leading digit
16791679
16801680 bool is_normal = unsigned (raw_exp - 1 ) < unsigned (traits::exp_mask - 1 );
16811681 if (!is_normal) [[ZMIJ_UNLIKELY]] {
1682- if (raw_exp != 0 ) // inf or nan
1683- return w.write (bin_sig != 0 ? " nan" : " inf" , 3 );
1682+ if (raw_exp != 0 ) return w.write (bin_sig != 0 ? " nan" : " inf" , 3 );
16841683 if (bin_sig != 0 ) normalize<double >(bin_sig, raw_exp);
16851684 bin_sig ^= traits::implicit_bit;
16861685 }
@@ -1705,16 +1704,15 @@ auto write_big(double value, int precision, char* out, size_t n,
17051704 num_digits = int (digits + sizeof (digits) - p);
17061705 lead_exp = num_digits - 1 + base_exp;
17071706
1708- // Significant digits to keep: precision, a leading digit for %e/%f, and the
1709- // remaining integer digits (lead_exp) for %f; %g counts significant digits.
1710- int max_digits = precision + !general;
1711- if (fixed) max_digits += lead_exp;
1707+ // Significant digits to keep: precision for %g. For %e/%f it counts
1708+ // fractional digits, so add one leading digit; %f adds lead_exp more.
1709+ int max_digits = precision + !general + (fixed ? lead_exp : 0 );
17121710 // Round to max_digits significant digits, ties to even.
17131711 if (max_digits < 1 ) {
17141712 // |value| < 10**-precision: rounds to 0, or up to 10**-precision when the
17151713 // discarded part exceeds half a unit (a tie rounds to even, i.e. 0).
17161714 bool round_up = false ;
1717- if (max_digits == 0 ) { // The rounded-away part starts at the lead digit.
1715+ if (max_digits == 0 ) {
17181716 round_up =
17191717 p[0 ] > ' 5' || (p[0 ] == ' 5' && any_nonzero (p + 1 , p + num_digits));
17201718 }
@@ -1725,7 +1723,7 @@ auto write_big(double value, int precision, char* out, size_t n,
17251723 } else if (num_digits > max_digits) {
17261724 char dropped = p[max_digits];
17271725 bool round_up = dropped > ' 5' ;
1728- // A dropped 5 is a tie unless a lower nonzero digit makes it sticky .
1726+ // A dropped 5 ties to even unless a lower nonzero digit rounds up .
17291727 if (dropped == ' 5' ) {
17301728 round_up = ((p[max_digits - 1 ] - ' 0' ) & 1 ) ||
17311729 any_nonzero (p + max_digits + 1 , p + num_digits);
@@ -1747,16 +1745,18 @@ auto write_big(double value, int precision, char* out, size_t n,
17471745 }
17481746
17491747 bool has_point = precision != 0 ; // %e: a point iff fractional digits
1748+ int num_frac_places = precision; // fractional digit positions to emit
17501749 if (general) {
17511750 // Drop trailing zeros and pick fixed or scientific.
17521751 while (num_digits > 1 && p[num_digits - 1 ] == ' 0' ) --num_digits;
17531752 fixed = lead_exp >= -4 && lead_exp < precision;
17541753 has_point = num_digits > 1 ;
1754+ num_frac_places = num_digits - lead_exp - 1 ;
17551755 }
17561756
17571757 if (!fixed) {
1758- // Scientific d.ddde±XX: %e pads to `precision` fractional digits, %g emits
1759- // only the significant ones.
1758+ // Emit scientific notation d.ddde±XX: %e pads to `precision` fractional
1759+ // digits, %g emits only the significant ones.
17601760 w.write (p[0 ]);
17611761 if (has_point) {
17621762 w.write (' .' );
@@ -1768,7 +1768,7 @@ auto write_big(double value, int precision, char* out, size_t n,
17681768 return w.write (exp, int (exp_end - exp));
17691769 }
17701770
1771- // Fixed notation.
1771+ // Emit fixed notation.
17721772 int point_pos = lead_exp + 1 ;
17731773 int num_int_digits = 0 ; // significant digits before the point
17741774 if (point_pos <= 0 ) { // |value| < 1, e.g. 0.00123
@@ -1778,16 +1778,13 @@ auto write_big(double value, int precision, char* out, size_t n,
17781778 w.write (p, num_int_digits);
17791779 w.write_zeros (point_pos - num_int_digits); // integer zeros, e.g. 12300
17801780 }
1781- // Characters after the decimal point: `precision` for %f (zero-padded), or
1782- // just the significant fractional digits for %g.
1783- int frac_width = general ? num_digits - point_pos : precision;
1784- if (frac_width <= 0 ) return w.out ; // no fractional part
1781+ if (num_frac_places <= 0 ) return w.out ;
17851782 w.write (' .' );
1786- int lead_zeros = point_pos < 0 ? -point_pos : 0 ;
1787- w.write_zeros (lead_zeros ); // 0.00...
1783+ int num_lead_zeros = point_pos < 0 ? -point_pos : 0 ;
1784+ w.write_zeros (num_lead_zeros ); // 0.00...
17881785 int num_frac_digits = num_digits - num_int_digits;
17891786 w.write (p + num_int_digits, num_frac_digits);
1790- return w.write_zeros (frac_width - lead_zeros - num_frac_digits);
1787+ return w.write_zeros (num_frac_places - num_lead_zeros - num_frac_digits);
17911788}
17921789
17931790template <typename Float>
0 commit comments