mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 19:47:34 +00:00
LibJS: Prevent i64 overflow when computing large NumberFormat exponents
The largest exponents we compute are on the order of 10^21 (governed by the maximumSignificantDigits option, which has a max value of 21). That is too large to fit into the i64 we were using when multiplying this exponent by the value to be formatted. Instead, split up the logic to multiply that value by this exponent based on the value's underlying type: Number: Do not cast the result of pow() to an i64, and perform the follow-up multiplication with doubles. BigInt: Do not use pow(). Instead, compute the exponent as a BigInt from the start, then perform the follow-up multiplication with that BigInt.
This commit is contained in:
parent
c367bcb5f8
commit
9e50f25ac4
2 changed files with 68 additions and 10 deletions
|
@ -78,6 +78,34 @@ describe("style=decimal", () => {
|
|||
expect(en.format(12.3456)).toBe("12.3456");
|
||||
expect(en.format(12.34567)).toBe("12.3457");
|
||||
expect(en.format(12.34561)).toBe("12.3456");
|
||||
expect(en.format(0.00000000000000000000000000000123)).toBe(
|
||||
"0.000000000000000000000000000001230"
|
||||
);
|
||||
expect(en.format(-0.00000000000000000000000000000123)).toBe(
|
||||
"-0.000000000000000000000000000001230"
|
||||
);
|
||||
expect(en.format(12344501000000000000000000000000000)).toBe(
|
||||
"12,344,500,000,000,000,000,000,000,000,000,000"
|
||||
);
|
||||
expect(en.format(-12344501000000000000000000000000000)).toBe(
|
||||
"-12,344,500,000,000,000,000,000,000,000,000,000"
|
||||
);
|
||||
expect(en.format(12344501000000000000000000000000000n)).toBe(
|
||||
"12,344,500,000,000,000,000,000,000,000,000,000"
|
||||
);
|
||||
expect(en.format(-12344501000000000000000000000000000n)).toBe(
|
||||
"-12,344,500,000,000,000,000,000,000,000,000,000"
|
||||
);
|
||||
|
||||
const enLargeMaxSignificantDigits = new Intl.NumberFormat("en", {
|
||||
minimumSignificantDigits: 4,
|
||||
maximumSignificantDigits: 21,
|
||||
});
|
||||
expect(enLargeMaxSignificantDigits.format(1)).toBe("1.000");
|
||||
expect(enLargeMaxSignificantDigits.format(1n)).toBe("1.000");
|
||||
expect(enLargeMaxSignificantDigits.format(123456789123456789123456789123456789n)).toBe(
|
||||
"123,456,789,123,456,789,123,000,000,000,000,000"
|
||||
);
|
||||
|
||||
const ar = new Intl.NumberFormat("ar", {
|
||||
minimumSignificantDigits: 4,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue