From 9fdb2b9653be6b2cfc6eb012a7915679ba9447cd Mon Sep 17 00:00:00 2001 From: He-Pin Date: Tue, 16 Jun 2026 14:35:51 +0800 Subject: [PATCH] fix: correct %g and %e exponent for powers of 10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Motivation: %g % 1000000 produced "1000000" instead of "1e+06", and %.2g % 1000 produced "10e+02" instead of "1e+03". Root cause: std.log(x)/std.log(10) suffers from floating-point imprecision for powers of 10 (e.g. log(1000000)/log(10) = 5.999999... instead of 6), causing std.floor to round down incorrectly. Modification: Added 1e-12 epsilon before std.floor in exponent calculation in both render_float_sci and the %g format handler. The epsilon is large enough to correct floating-point error (~1e-15) but small enough to not affect non-power-of-10 values. Result: - "%g" % 1000000 → "1e+06" (was "1000000") - "%.2g" % 1000 → "1e+03" (was "10e+02") - "%e" % 1000000 → "1.000000e+06" (was "1.000000e+05" with wrong mantissa) - All other %g/%e cases unchanged. --- stdlib/std.jsonnet | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/std.jsonnet b/stdlib/std.jsonnet index 9eee818ff..2d143d090 100644 --- a/stdlib/std.jsonnet +++ b/stdlib/std.jsonnet @@ -613,7 +613,7 @@ limitations under the License. // Render floating point in scientific form local render_float_sci(n__, zero_pad, blank, plus, ensure_pt, trailing, caps, prec) = - local exponent = if n__ == 0 then 0 else std.floor(std.log(std.abs(n__)) / std.log(10)); + local exponent = if n__ == 0 then 0 else std.floor(std.log(std.abs(n__)) / std.log(10) + 1e-12); local suff = (if caps then 'E' else 'e') + render_int(exponent < 0, std.abs(exponent), 3, 0, false, true, 10, ''); local mantissa = if exponent == -324 then @@ -688,7 +688,7 @@ limitations under the License. error 'Format required number at ' + i + ', got ' + std.type(val) else - local exponent = if val != 0 then std.floor(std.log(std.abs(val)) / std.log(10)) else 0; + local exponent = if val != 0 then std.floor(std.log(std.abs(val)) / std.log(10) + 1e-12) else 0; if exponent < -4 || exponent >= fpprec then render_float_sci(val, zp,