|
@@ -232,44 +232,30 @@ JS_DEFINE_NATIVE_FUNCTION(NumberPrototype::to_fixed)
|
|
|
number = -number;
|
|
|
|
|
|
// 10. If x ≥ 10^21, then
|
|
|
- if (fabs(number) >= 1e+21)
|
|
|
+ // a. Let m be ! ToString(𝔽(x)).
|
|
|
+ if (number >= 1e+21)
|
|
|
return PrimitiveString::create(vm, MUST(number_value.to_deprecated_string(vm)));
|
|
|
|
|
|
// 11. Else,
|
|
|
- // a. Let n be an integer for which n / (10^f) - x is as close to zero as possible. If there are two such n, pick the larger n.
|
|
|
- // FIXME: This breaks down with values of `fraction_digits` > 23
|
|
|
- auto n = round(pow(10.0f, fraction_digits) * number);
|
|
|
-
|
|
|
- // b. If n = 0, let m be the String "0". Otherwise, let m be the String value consisting of the digits of the decimal representation of n (in order, with no leading zeroes).
|
|
|
- auto m = (n == 0 ? "0" : DeprecatedString::formatted("{}", n));
|
|
|
-
|
|
|
- // c. If f ≠ 0, then
|
|
|
- if (fraction_digits != 0) {
|
|
|
- // i. Let k be the length of m.
|
|
|
- auto k = static_cast<size_t>(m.length());
|
|
|
-
|
|
|
- // ii. If k ≤ f, then
|
|
|
- if (k <= fraction_digits) {
|
|
|
- // 1. Let z be the String value consisting of f + 1 - k occurrences of the code unit 0x0030 (DIGIT ZERO).
|
|
|
- auto z = DeprecatedString::repeated('0', fraction_digits + 1 - k);
|
|
|
-
|
|
|
- // 2. Set m to the string-concatenation of z and m.
|
|
|
- m = DeprecatedString::formatted("{}{}", z, m);
|
|
|
+ // a. Let n be an integer for which n / (10^f) - x is as close to zero as possible. If there are two such n, pick the larger n.
|
|
|
+ // b. If n = 0, let m be the String "0". Otherwise, let m be the String value consisting of the digits of the decimal representation of n (in order, with no leading zeroes).
|
|
|
+ // c. If f ≠ 0, then
|
|
|
+ // i. Let k be the length of m.
|
|
|
+ // ii. If k ≤ f, then
|
|
|
+ // 1. Let z be the String value consisting of f + 1 - k occurrences of the code unit 0x0030 (DIGIT ZERO).
|
|
|
+ // 2. Set m to the string-concatenation of z and m.
|
|
|
+ // 3. Set k to f + 1.
|
|
|
+ // iii. Let a be the first k - f code units of m.
|
|
|
+ // iv. Let b be the other f code units of m.
|
|
|
+ // v. Set m to the string-concatenation of a, ".", and b.
|
|
|
+ // 12. Return the string-concatenation of s and m.
|
|
|
|
|
|
- // 3. Set k to f + 1.
|
|
|
- k = fraction_digits + 1;
|
|
|
- }
|
|
|
+ // NOTE: the above steps are effectively trying to create a formatted string of the
|
|
|
+ // `number` double. Instead of generating a huge, unwieldy `n`, we format
|
|
|
+ // the double using our existing formatting code.
|
|
|
|
|
|
- // iii. Let a be the first k - f code units of m.
|
|
|
- // iv. Let b be the other f code units of m.
|
|
|
- // v. Set m to the string-concatenation of a, ".", and b.
|
|
|
- m = DeprecatedString::formatted("{}.{}",
|
|
|
- m.substring_view(0, k - fraction_digits),
|
|
|
- m.substring_view(k - fraction_digits, fraction_digits));
|
|
|
- }
|
|
|
-
|
|
|
- // 12. Return the string-concatenation of s and m.
|
|
|
- return PrimitiveString::create(vm, DeprecatedString::formatted("{}{}", s, m));
|
|
|
+ auto number_format_string = DeprecatedString::formatted("{{}}{{:.{}f}}", fraction_digits);
|
|
|
+ return PrimitiveString::create(vm, DeprecatedString::formatted(number_format_string, s, number));
|
|
|
}
|
|
|
|
|
|
// 19.2.1 Number.prototype.toLocaleString ( [ locales [ , options ] ] ), https://tc39.es/ecma402/#sup-number.prototype.tolocalestring
|