LibJS: Use more accurate number-to-string method in Intl.NumberFormat

Intl.NumberFormat only ever wants literal number-to-digits here, without
extra exponential formatting.
This commit is contained in:
Timothy Flynn 2022-11-04 08:53:23 -04:00 committed by Linus Groh
parent 9620a092de
commit d56205f991
Notes: sideshowbarker 2024-07-17 06:40:21 +09:00
3 changed files with 14 additions and 6 deletions

View file

@ -296,7 +296,7 @@ bool MathematicalValue::is_zero() const
String MathematicalValue::to_string() const
{
return m_value.visit(
[](double value) { return Value(value).to_string_without_side_effects(); },
[](double value) { return number_to_string(value, NumberToStringMode::WithoutExponent); },
[](Crypto::SignedBigInteger const& value) { return value.to_base(10); },
[](auto) -> String { VERIFY_NOT_REACHED(); });
}

View file

@ -1032,11 +1032,6 @@ RawFormatResult to_raw_precision(MathematicalValue const& number, int min_precis
}
// 3. Else,
else {
// FIXME: The result of these steps isn't entirely accurate for large values of 'p' (which
// defaults to 21, resulting in numbers on the order of 10^21). Either AK::format or
// our Number::toString AO (double_to_string in Value.cpp) will need to be improved
// to produce more accurate results.
// a. Let n1 and e1 each be an integer and r1 a mathematical value, with r1 = ToRawPrecisionFn(n1, e1, p), such that r1 ≤ x and r1 is maximized.
auto [number1, exponent1, rounded1] = to_raw_precision_function(number, precision, PreferredResult::LessThanNumber);

View file

@ -135,6 +135,12 @@ describe("style=decimal", () => {
expect(en.format(1.23456)).toBe("1.23456");
expect(en.format(1.234567)).toBe("1.23457");
expect(en.format(1.234561)).toBe("1.23456");
expect(en.format("12344501000000000000000000000000000")).toBe(
"12,344,501,000,000,000,000,000,000,000,000,000.000"
);
expect(en.format("-12344501000000000000000000000000000")).toBe(
"-12,344,501,000,000,000,000,000,000,000,000,000.000"
);
const ar = new Intl.NumberFormat("ar", {
minimumFractionDigits: 3,
@ -149,6 +155,13 @@ describe("style=decimal", () => {
expect(ar.format(1.23456)).toBe("\u0661\u066b\u0662\u0663\u0664\u0665\u0666");
expect(ar.format(1.234567)).toBe("\u0661\u066b\u0662\u0663\u0664\u0665\u0667");
expect(ar.format(1.234561)).toBe("\u0661\u066b\u0662\u0663\u0664\u0665\u0666");
let digits = "\u0661\u0662\u066c\u0663\u0664\u0664\u066c\u0665\u0660\u0661";
digits += "\u066c\u0660\u0660\u0660".repeat(9);
digits += "\u066b\u0660\u0660\u0660";
expect(ar.format("12344501000000000000000000000000000")).toBe(digits);
expect(ar.format("-12344501000000000000000000000000000")).toBe("\u061c-" + digits);
});
test("notation=scientific", () => {