diff --git a/Userland/Libraries/LibJS/Runtime/Value.cpp b/Userland/Libraries/LibJS/Runtime/Value.cpp index bf00d3780e..7a7a0e3756 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.cpp +++ b/Userland/Libraries/LibJS/Runtime/Value.cpp @@ -71,7 +71,7 @@ ALWAYS_INLINE bool both_bigint(Value const& lhs, Value const& rhs) // 6.1.6.1.20 Number::toString ( x ), https://tc39.es/ecma262/#sec-numeric-types-number-tostring // Implementation for radix = 10 -static String double_to_string(double d) +String number_to_string(double d, NumberToStringMode mode) { auto convert_to_decimal_digits_array = [](auto x, auto& digits, auto& length) { for (; x; x /= 10) @@ -116,8 +116,12 @@ static String double_to_string(double d) if (sign) builder.append('-'); + // Non-standard: Intl needs number-to-string conversions for extremely large numbers without any + // exponential formatting, as it will handle such formatting itself in a locale-aware way. + bool force_no_exponent = mode == NumberToStringMode::WithoutExponent; + // 6. If radix ≠ 10 or n is in the inclusive interval from -5 to 21, then - if (n >= -5 && n <= 21) { + if ((n >= -5 && n <= 21) || force_no_exponent) { // a. If n ≥ k, then if (n >= k) { // i. Return the string-concatenation of: @@ -299,7 +303,7 @@ String Value::typeof() const String Value::to_string_without_side_effects() const { if (is_double()) - return double_to_string(m_value.as_double); + return number_to_string(m_value.as_double); switch (m_value.tag) { case UNDEFINED_TAG: @@ -337,7 +341,7 @@ ThrowCompletionOr Value::to_primitive_string(VM& vm) ThrowCompletionOr Value::to_string(VM& vm) const { if (is_double()) - return double_to_string(m_value.as_double); + return number_to_string(m_value.as_double); switch (m_value.tag) { case UNDEFINED_TAG: diff --git a/Userland/Libraries/LibJS/Runtime/Value.h b/Userland/Libraries/LibJS/Runtime/Value.h index ef65ca09cc..f23c3dc881 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.h +++ b/Userland/Libraries/LibJS/Runtime/Value.h @@ -564,6 +564,11 @@ ThrowCompletionOr is_less_than(VM&, Value lhs, Value rhs, bool left_fi double to_integer_or_infinity(double); +enum class NumberToStringMode { + WithExponent, + WithoutExponent, +}; +String number_to_string(double, NumberToStringMode = NumberToStringMode::WithExponent); Optional string_to_number(StringView); inline bool Value::operator==(Value const& value) const { return same_value(*this, value); }