Skip to content

fix: preserve exact binary64 digits in decimal formats - #1097

Merged
stephenamar-db merged 2 commits into
databricks:masterfrom
He-Pin:fix/format-exact-binary64-precision
Jul 30, 2026
Merged

fix: preserve exact binary64 digits in decimal formats#1097
stephenamar-db merged 2 commits into
databricks:masterfrom
He-Pin:fix/format-exact-binary64-precision

Conversation

@He-Pin

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

Copy link
Copy Markdown
Contributor

Motivation

BigDecimal(number) uses the shortest round-trip decimal, not the exact binary64 value. When %f or fixed-form %g requested >15 digits, sjsonnet padded the shortened decimal and hid meaningful trailing digits.

Modification

  • Use BigDecimal.exact(number) for fixed formatting above 15 fractional digits.
  • Propagate %g's significant precision so its fixed-form path can select exact conversion.
  • Round the exact path with half-even semantics; preserve existing low-precision behavior.
  • Add non-tie, retained-even/odd halfway, negative halfway, and fixed-form %g regressions.

Result

Expression before after go-jsonnet jrsonnet Python
std.format("%.16f", 3.14159265358979323) 3.1415926535897930 3.1415926535897931 3.1415926535897932 3.1415926535897932 3.1415926535897931
std.format("%.17f", 0.1) 0.10000000000000000 0.10000000000000001 0.10000000000000000 0.10000000000000002 0.10000000000000001
std.format("%.17f", 3.14159265358979323) 3.14159265358979300 3.14159265358979312 3.14159265358979328 3.14159265358979328 3.14159265358979312
std.format("%.17g", 31.4159265358979323) 31.41592653589793 31.415926535897931 31.415926535897932 31.415926535897932 31.415926535897931

Half-even rounding verified against go-jsonnet, jrsonnet, and Python. Full matrix (JVM/JS/Wasm/Native) + checkFormat passed.

High-precision scientific notation is handled separately in #1095.

References

Motivation:
High-precision %f and fixed-form %g formatting started from the shortest
round-tripping decimal string, hiding meaningful trailing digits of the
binary64 value.

Modification:
Use the exact binary64 decimal value when fixed formatting needs more than 15
digits, propagate the original %g significant precision, and use half-even
rounding for the exact path. Add non-tie and exact-halfway regressions while
preserving the public five-argument JVM descriptor.

Result:
High-precision fixed decimal output matches Python from the same IEEE-754
value, including ties-to-even, without changing the legacy low-precision
rounding path or JVM binary compatibility.

References:
- databricks#1097
- https://jsonnet.org/ref/stdlib.html#std-format
@He-Pin
He-Pin force-pushed the fix/format-exact-binary64-precision branch from 44d9ecb to c5677c3 Compare July 29, 2026 08:27
@He-Pin He-Pin changed the title Use exact binary64 values for fixed decimal formatting fix: preserve exact binary64 digits in decimal formats Jul 29, 2026
Motivation:
The original tests lacked coverage at the precision 15/16 threshold
(where the code switches from legacy to exact path) and for extreme
values like subnormals and the %g fixed-form path.

Modification:
Add assertions for: precision-15 boundary (pi), %.20f of 0.1 and
1e-10 (exact binary64 trailing digits), subnormal 5e-324 at %.16f,
and %.20g exercising the useExactDecimal parameter propagation.

Result:
The precision threshold and edge cases are now regression-protected.
@stephenamar-db
stephenamar-db merged commit 755f99e into databricks:master Jul 30, 2026
5 checks passed
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.

2 participants