Skip to content

fix: format high-precision scientific numbers exactly - #1095

Open
He-Pin wants to merge 2 commits into
databricks:masterfrom
He-Pin:fix/format-scientific-high-precision
Open

fix: format high-precision scientific numbers exactly#1095
He-Pin wants to merge 2 commits into
databricks:masterfrom
He-Pin:fix/format-scientific-high-precision

Conversation

@He-Pin

@He-Pin He-Pin commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Motivation

The old scientific path scaled in Double and rounded through Long. Precision above 15 could lose meaningful binary64 digits; precision ≥19 saturated at Long.MaxValue, producing silent wrong answers (e.g. std.format("%.19e", 1.5)1.000...e+00).

Modification

  • For scientific precision >15, use BigDecimal.exact(number) with BigInt mantissa scaling.
  • Round with half-even semantics; propagate carry into exponent without Long narrowing.
  • Add regressions for precision 16–20, exponent boundaries, exact ties, signed zero, %E.

Result

Expression before after go-jsonnet jrsonnet Python
std.format("%.16e", 3.14159265358979323) 3.1415926535897932e+00 3.1415926535897931e+00 3.1415926535897932e+00 3.1415926535897932e+00 3.1415926535897931e+00
std.format("%.19e", 1.5) 1.0000000000000000000e+00 1.5000000000000000000e+00 1.5000000000000000000e+00 1.5000000000000000000e+00 1.5000000000000000000e+00
std.format("%.19e", 0.1) 1.0000000000000000000e-01 1.0000000000000000555e-01 1.0000000000000000000e-01 1.0000000000000000000e-01 1.0000000000000000555e-01
std.format("%.20e", 3.14) 1.00000000000000000000e+00 3.14000000000000012434e+00 3.14000000000000000000e+00 3.09223372036854775807e+00 3.14000000000000012434e+00

This PR matches Python's formatting model from the exact binary64 value. Full matrix (JVM/JS/Wasm/Native) + checkFormat passed.

References

Motivation:
Scientific formatting scaled binary64 values in Double and rounded through
Long. Precision above 15 lost low-order digits, and precision 19 or greater
could saturate at Long.MaxValue and silently replace the mantissa.

Modification:
Use the exact binary64 magnitude, BigInt scaling, half-even rounding, corrected
decimal-exponent bounds, and carry handling for scientific precision above 15.
Add regressions for precision 16 through 20, decade boundaries, ties, signed
zero, and uppercase formatting.

Result:
High-precision %e/%E output no longer saturates and matches Python formatting
from the same IEEE-754 value, including exact trailing digits.

References:
- databricks#1095
- https://jsonnet.org/ref/stdlib.html#std-format
@He-Pin
He-Pin force-pushed the fix/format-scientific-high-precision branch from f291f79 to eb3f89d Compare July 29, 2026 08:27
@He-Pin He-Pin changed the title Fix high-precision scientific formatting fix: format high-precision scientific numbers exactly Jul 29, 2026
Motivation:
The original test only covered precision 16-20 with moderate values.
Double.MaxValue, the smallest subnormal, and precision > 20 were
verified manually but not regression-protected.

Modification:
Add assertions for Double.MaxValue (%.20e), smallest subnormal 5e-324
(%.20e), precision 40, precision 25, and pi at precision 30.

Result:
Extreme edge cases are now locked in against future regressions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant