Skip to content

topdown: fix format_int precision loss for integers larger than 64 bits#8857

Open
Synvoya wants to merge 2 commits into
open-policy-agent:mainfrom
Synvoya:fix/format-int-bignum-precision
Open

topdown: fix format_int precision loss for integers larger than 64 bits#8857
Synvoya wants to merge 2 commits into
open-policy-agent:mainfrom
Synvoya:fix/format-int-bignum-precision

Conversation

@Synvoya

@Synvoya Synvoya commented Jul 3, 2026

Copy link
Copy Markdown

Description

format_int(x, base) corrupts integers that need more than 64 bits of precision, in every base. It routes the value through builtins.NumberToFloat (a big.Float with a 64-bit mantissa) then f.Int(), so any integer above ~2^64 is rounded before formatting:

format_int(18446744073709551617, 16)   # "10000000000000000"    (should be "10000000000000001")
format_int(18446744073709551617, 10)   # "18446744073709551616" (should be "...617")

sprintf("%x", [18446744073709551617]) returns the correct 10000000000000001, so two builtins disagree on the same exact-integer value.

Fix

Format integer inputs through an exact big.Int (mirroring builtinSprintf). Fractional/exponent inputs still fall through to the existing float-truncation path, so format_int(15.9, 16) == "f" and format_int(-15.9, 16) == "-f" are unchanged.

Test

Added a golden case covering a >2^64 integer in bases 2/8/10/16, negatives, and the fractional-truncation cases. Full go test ./v1/topdown/ passes (900+ existing string golden cases, no regressions).

Synvoya added 2 commits July 4, 2026 01:06
format_int routed integers through a 64-bit-mantissa big.Float, corrupting any value above ~2^64 (disagreeing with sprintf). Format integer inputs through an exact big.Int; fractional inputs keep float truncation.

Signed-off-by: Synvoya <16019863+Synvoya@users.noreply.github.com>
WASM's format_int cannot represent integers larger than 64 bits (get uint failed), the same limitation already tracked for integer literals (open-policy-agent#3711). Add the new golden case to the WASM e2e exceptions so it runs under Go (where the fix applies) but is skipped under WASM.

Signed-off-by: Synvoya <16019863+Synvoya@users.noreply.github.com>
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