Skip to content

Commit 4d268ff

Browse files
committed
Clarify write_big comments and rounding wording
Explain how precision maps to significant digits per format, reword the tie-breaking comment to drop misapplied "sticky" jargon, and make the notation labels verb-led sentences.
1 parent 033be67 commit 4d268ff

1 file changed

Lines changed: 18 additions & 21 deletions

File tree

zmij.cc

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -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

17931790
template <typename Float>

0 commit comments

Comments
 (0)