Skip to content

Conversation

@sffc
Copy link
Contributor

@sffc sffc commented Aug 9, 2025

See #1017

The intent of this PR is the following. In this table, 99~9 stands in for 9999 digit 9s, and 999~9 stands in for 10000 digit 9s.

Input String MV Resolved MV Comments
1e9999 1e9999
99~9e9999 99~9e9999
99~9.999~9e9999 99~9.999~9e9999 Largest in-bounds value
1e10000 Smallest out-of-bounds value
1e-10000 1e-10000 Smallest in-bounds value
9e-10001 0
0.999~9 0.999~9
0.999~98 0.999~9 Truncate such that the least significant digit is at 1e-10000
1.9e-10000 1e-10000 ^
1.234e-9998 1.23e-9998 ^

@sffc
Copy link
Contributor Author

sffc commented Aug 9, 2025

@sffc
Copy link
Contributor Author

sffc commented Aug 9, 2025

Just a note on the significant digits truncation: this could technically change the behavior of numbers so close to the edge of a rounding boundary where the discriminator is at a position less than -10000; for example, 2.5 followed by 10000 zeros followed by 1, with half-even rounding. In the current spec, that number should round up to 3, but in this new spec, that number should round down to 2 since the significant digit is dropped during parsing, not during rounding. I think people like to call this "double rounding".

If this is a problem (it might not be: 10000 digits is beyond all known use cases), it can be fixed by performing a bigger refactoring of the spec in order to avoid the spec-required double rounding, but actually it is easier to implement if the truncation happens during parsing.

@sffc sffc moved this to Priority Issues in ECMA-402 Meeting Topics Aug 13, 2025
@eemeli
Copy link
Member

eemeli commented Aug 14, 2025

Could someone confirm that this approach would not cause any issues with implementations that rely on ICU4C or ICU4J?

@sffc
Copy link
Contributor Author

sffc commented Aug 14, 2025

ICU4C (and ICU4J) have a similar representation as ICU4X but use int32_t for the fields.

https://github.com/unicode-org/icu/blob/3a66f8c5fecfc3f0ee427c12b90966bac1b02d92/icu4c/source/i18n/number_decimalquantity.h#L361

@sffc
Copy link
Contributor Author

sffc commented Aug 15, 2025

@sffc
Copy link
Contributor Author

sffc commented Aug 15, 2025

@erights It was suggested that we bring this PR to TG3. Could it be added to an upcoming TG3 agenda?

@erights
Copy link

erights commented Aug 15, 2025 via email

@sffc
Copy link
Contributor Author

sffc commented Sep 11, 2025

1. If _rounded_ is *+∞*<sub>𝔽</sub>, return ~positive-infinity~.
1. If _rounded_ is *+0*<sub>𝔽</sub> and _intlMV_ &lt; 0, return ~negative-zero~.
1. If _rounded_ is *+0*<sub>𝔽</sub>, return 0.
1. Let _e_ be the integer such that 10<sup>_e_</sup> ≤ abs(_intlMV_) &lt; 10<sup>_e_ + 1</sup>.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choosing such an e is impossible if intlMV is zero. To fix it, handle the zero case separately.

@waldemarhorwat
Copy link

The description above doesn't match what the algorithm is doing. I assume this is due to typos in the description? I don't see why 10e9999 would be in-bounds while 1e10000 would be out of bounds (it's the same mathematical value), which is what the description above is currently stating.

The algorithm changes look good, once the bug when intlMV is zero is fixed.

@sffc sffc moved this from Priority Issues to Previously Discussed in ECMA-402 Meeting Topics Oct 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Previously Discussed

Development

Successfully merging this pull request may close these issues.

5 participants