Repository navigation
fix(number): emit round-trip digits in Number.prototype.toString(radix) - #5645
Open
rishabhknowss wants to merge 1 commit into
Open
rishabhknowss wants to merge 1 commit into
rishabhknowss wants to merge 1 commit into
Conversation
The radix conversion was ported from V8 and computes digits in floating point, so for radices that are not powers of two the output often does not read back as the input. Generate the shortest digits with exact integer arithmetic (Burger and Dybvig's free-format algorithm) instead. Closes boa-dev#5636 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This Pull Request fixes/closes #5636.
the radix path was a port of v8's DoubleToRadixCString, which works in floating point, so for radices that aren't powers of two the digits often don't read back as the input. on main,
(0.6206327010376135).toString(36)gives0.mcc8m4rgeand(1e21).toString(36)gives5v1j4f4ds7c000, neither of which round-trips.it changes the following:
to_js_string_radixnow uses burger & dybvig's free-format algorithm onBigUint(num-bigint is already a dependency). it produces the shortest digits that round back to the input, for any radix (Number::toString step 5).next_afterandBUF_SIZE, which only the old path used.to_string_non_power_of_two_radixwith the examples from the issue plus a few edge cases (subnormal, MAX_VALUE, negative, exact thirds). it fails on main.i also checked it against 20,303 doubles × 9 radices with an exact checker: parse the output as a rational, round to the nearest double, and confirm no shorter digit string rounds back. all 182,727 outputs pass. the same checker flags ~71k outputs from node. radix 2 and 16 output is byte-identical to main.
testing:
cargo test -p boa_engine: all passcargo clippy -p boa_engine --all-targets -- -D warnings, with--all-featuresand--no-default-features: cleancargo fmt --all --check: cleancargo make run-ci(the pre-push hook): passesbuilt-ins/Number/prototype/toString: 90/90.built-ins/Number: 339/340 on both main and this branch (same pre-existing failure)two things worth a look:
issue_2717expected0.8aoosla2phjfor(0.23046743672210102).toString(36).h,iandjall round back to the input and the spec leaves that choice open, so it now gives0.8aoosla2phh, the closest one.AI assistance: Claude Code