Commit 11256376 authored by Daniel Ehrenberg's avatar Daniel Ehrenberg Committed by Commit Bot

[builtins] Increase precision limits for toFixed, etc

This patch implements a recent spec change [1] which increases the
bounds of precision for toFixed, toExponential and toPrecision.
The bounds are a compromise between SpiderMonkey and the other
engines.

[1] https://github.com/tc39/ecma262/pull/857

Bug: v8:6539
Cq-Include-Trybots: master.tryserver.v8:v8_linux_noi18n_rel_ng
Change-Id: I877aa35e08f3dcda63f5f9181fdecf3c227f2c35
Reviewed-on: https://chromium-review.googlesource.com/553378
Commit-Queue: Daniel Ehrenberg <littledan@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46793}
parent a224eff4
...@@ -44,7 +44,8 @@ BUILTIN(NumberPrototypeToExponential) { ...@@ -44,7 +44,8 @@ BUILTIN(NumberPrototypeToExponential) {
return (value_number < 0.0) ? isolate->heap()->minus_Infinity_string() return (value_number < 0.0) ? isolate->heap()->minus_Infinity_string()
: isolate->heap()->Infinity_string(); : isolate->heap()->Infinity_string();
} }
if (fraction_digits_number < 0.0 || fraction_digits_number > 20.0) { if (fraction_digits_number < 0.0 ||
fraction_digits_number > kMaxFractionDigits) {
THROW_NEW_ERROR_RETURN_FAILURE( THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewRangeError(MessageTemplate::kNumberFormatRange, isolate, NewRangeError(MessageTemplate::kNumberFormatRange,
isolate->factory()->NewStringFromAsciiChecked( isolate->factory()->NewStringFromAsciiChecked(
...@@ -84,7 +85,8 @@ BUILTIN(NumberPrototypeToFixed) { ...@@ -84,7 +85,8 @@ BUILTIN(NumberPrototypeToFixed) {
double const fraction_digits_number = fraction_digits->Number(); double const fraction_digits_number = fraction_digits->Number();
// Check if the {fraction_digits} are in the supported range. // Check if the {fraction_digits} are in the supported range.
if (fraction_digits_number < 0.0 || fraction_digits_number > 20.0) { if (fraction_digits_number < 0.0 ||
fraction_digits_number > kMaxFractionDigits) {
THROW_NEW_ERROR_RETURN_FAILURE( THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewRangeError(MessageTemplate::kNumberFormatRange, isolate, NewRangeError(MessageTemplate::kNumberFormatRange,
isolate->factory()->NewStringFromAsciiChecked( isolate->factory()->NewStringFromAsciiChecked(
...@@ -158,7 +160,7 @@ BUILTIN(NumberPrototypeToPrecision) { ...@@ -158,7 +160,7 @@ BUILTIN(NumberPrototypeToPrecision) {
return (value_number < 0.0) ? isolate->heap()->minus_Infinity_string() return (value_number < 0.0) ? isolate->heap()->minus_Infinity_string()
: isolate->heap()->Infinity_string(); : isolate->heap()->Infinity_string();
} }
if (precision_number < 1.0 || precision_number > 21.0) { if (precision_number < 1.0 || precision_number > kMaxFractionDigits) {
THROW_NEW_ERROR_RETURN_FAILURE( THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewRangeError(MessageTemplate::kToPrecisionFormatRange)); isolate, NewRangeError(MessageTemplate::kToPrecisionFormatRange));
} }
......
...@@ -201,9 +201,8 @@ const char* IntToCString(int n, Vector<char> buffer) { ...@@ -201,9 +201,8 @@ const char* IntToCString(int n, Vector<char> buffer) {
char* DoubleToFixedCString(double value, int f) { char* DoubleToFixedCString(double value, int f) {
const int kMaxDigitsBeforePoint = 21; const int kMaxDigitsBeforePoint = 21;
const double kFirstNonFixed = 1e21; const double kFirstNonFixed = 1e21;
const int kMaxDigitsAfterPoint = 20;
DCHECK(f >= 0); DCHECK(f >= 0);
DCHECK(f <= kMaxDigitsAfterPoint); DCHECK(f <= kMaxFractionDigits);
bool negative = false; bool negative = false;
double abs_value = value; double abs_value = value;
...@@ -215,7 +214,7 @@ char* DoubleToFixedCString(double value, int f) { ...@@ -215,7 +214,7 @@ char* DoubleToFixedCString(double value, int f) {
// If abs_value has more than kMaxDigitsBeforePoint digits before the point // If abs_value has more than kMaxDigitsBeforePoint digits before the point
// use the non-fixed conversion routine. // use the non-fixed conversion routine.
if (abs_value >= kFirstNonFixed) { if (abs_value >= kFirstNonFixed) {
char arr[100]; char arr[kMaxFractionDigits];
Vector<char> buffer(arr, arraysize(arr)); Vector<char> buffer(arr, arraysize(arr));
return StrDup(DoubleToCString(value, buffer)); return StrDup(DoubleToCString(value, buffer));
} }
...@@ -225,7 +224,7 @@ char* DoubleToFixedCString(double value, int f) { ...@@ -225,7 +224,7 @@ char* DoubleToFixedCString(double value, int f) {
int sign; int sign;
// Add space for the '\0' byte. // Add space for the '\0' byte.
const int kDecimalRepCapacity = const int kDecimalRepCapacity =
kMaxDigitsBeforePoint + kMaxDigitsAfterPoint + 1; kMaxDigitsBeforePoint + kMaxFractionDigits + 1;
char decimal_rep[kDecimalRepCapacity]; char decimal_rep[kDecimalRepCapacity];
int decimal_rep_length; int decimal_rep_length;
DoubleToAscii(value, DTOA_FIXED, f, DoubleToAscii(value, DTOA_FIXED, f,
...@@ -302,9 +301,8 @@ static char* CreateExponentialRepresentation(char* decimal_rep, ...@@ -302,9 +301,8 @@ static char* CreateExponentialRepresentation(char* decimal_rep,
char* DoubleToExponentialCString(double value, int f) { char* DoubleToExponentialCString(double value, int f) {
const int kMaxDigitsAfterPoint = 20;
// f might be -1 to signal that f was undefined in JavaScript. // f might be -1 to signal that f was undefined in JavaScript.
DCHECK(f >= -1 && f <= kMaxDigitsAfterPoint); DCHECK(f >= -1 && f <= kMaxFractionDigits);
bool negative = false; bool negative = false;
if (value < 0) { if (value < 0) {
...@@ -318,10 +316,10 @@ char* DoubleToExponentialCString(double value, int f) { ...@@ -318,10 +316,10 @@ char* DoubleToExponentialCString(double value, int f) {
// f corresponds to the digits after the point. There is always one digit // f corresponds to the digits after the point. There is always one digit
// before the point. The number of requested_digits equals hence f + 1. // before the point. The number of requested_digits equals hence f + 1.
// And we have to add one character for the null-terminator. // And we have to add one character for the null-terminator.
const int kV8DtoaBufferCapacity = kMaxDigitsAfterPoint + 1 + 1; const int kV8DtoaBufferCapacity = kMaxFractionDigits + 1 + 1;
// Make sure that the buffer is big enough, even if we fall back to the // Make sure that the buffer is big enough, even if we fall back to the
// shortest representation (which happens when f equals -1). // shortest representation (which happens when f equals -1).
DCHECK(kBase10MaximalLength <= kMaxDigitsAfterPoint + 1); DCHECK(kBase10MaximalLength <= kMaxFractionDigits + 1);
char decimal_rep[kV8DtoaBufferCapacity]; char decimal_rep[kV8DtoaBufferCapacity];
int decimal_rep_length; int decimal_rep_length;
...@@ -348,8 +346,7 @@ char* DoubleToExponentialCString(double value, int f) { ...@@ -348,8 +346,7 @@ char* DoubleToExponentialCString(double value, int f) {
char* DoubleToPrecisionCString(double value, int p) { char* DoubleToPrecisionCString(double value, int p) {
const int kMinimalDigits = 1; const int kMinimalDigits = 1;
const int kMaximalDigits = 21; DCHECK(p >= kMinimalDigits && p <= kMaxFractionDigits);
DCHECK(p >= kMinimalDigits && p <= kMaximalDigits);
USE(kMinimalDigits); USE(kMinimalDigits);
bool negative = false; bool negative = false;
...@@ -362,7 +359,7 @@ char* DoubleToPrecisionCString(double value, int p) { ...@@ -362,7 +359,7 @@ char* DoubleToPrecisionCString(double value, int p) {
int decimal_point; int decimal_point;
int sign; int sign;
// Add one for the terminating null character. // Add one for the terminating null character.
const int kV8DtoaBufferCapacity = kMaximalDigits + 1; const int kV8DtoaBufferCapacity = kMaxFractionDigits + 1;
char decimal_rep[kV8DtoaBufferCapacity]; char decimal_rep[kV8DtoaBufferCapacity];
int decimal_rep_length; int decimal_rep_length;
......
...@@ -26,6 +26,9 @@ class UnicodeCache; ...@@ -26,6 +26,9 @@ class UnicodeCache;
// we don't need to preserve all the digits. // we don't need to preserve all the digits.
const int kMaxSignificantDigits = 772; const int kMaxSignificantDigits = 772;
// The limit for the the fractionDigits/precision for toFixed, toPrecision
// and toExponential.
const int kMaxFractionDigits = 100;
inline bool isDigit(int x, int radix) { inline bool isDigit(int x, int radix) {
return (x >= '0' && x <= '9' && x < '0' + radix) return (x >= '0' && x <= '9' && x < '0' + radix)
......
...@@ -527,10 +527,11 @@ class ErrorUtils : public AllStatic { ...@@ -527,10 +527,11 @@ class ErrorUtils : public AllStatic {
T(LetInLexicalBinding, "let is disallowed as a lexically bound name") \ T(LetInLexicalBinding, "let is disallowed as a lexically bound name") \
T(LocaleMatcher, "Illegal value for localeMatcher:%") \ T(LocaleMatcher, "Illegal value for localeMatcher:%") \
T(NormalizationForm, "The normalization form should be one of %.") \ T(NormalizationForm, "The normalization form should be one of %.") \
T(NumberFormatRange, "% argument must be between 0 and 20") \ T(NumberFormatRange, "% argument must be between 0 and 100") \
T(PropertyValueOutOfRange, "% value is out of range.") \ T(PropertyValueOutOfRange, "% value is out of range.") \
T(StackOverflow, "Maximum call stack size exceeded") \ T(StackOverflow, "Maximum call stack size exceeded") \
T(ToPrecisionFormatRange, "toPrecision() argument must be between 1 and 21") \ T(ToPrecisionFormatRange, \
"toPrecision() argument must be between 1 and 100") \
T(ToRadixFormatRange, "toString() radix argument must be between 2 and 36") \ T(ToRadixFormatRange, "toString() radix argument must be between 2 and 36") \
T(TypedArraySetNegativeOffset, "Start offset is negative") \ T(TypedArraySetNegativeOffset, "Start offset is negative") \
T(TypedArraySetSourceTooLarge, "Source is too large") \ T(TypedArraySetSourceTooLarge, "Source is too large") \
......
...@@ -426,12 +426,12 @@ test(function() { ...@@ -426,12 +426,12 @@ test(function() {
// kNumberFormatRange // kNumberFormatRange
test(function() { test(function() {
Number(1).toFixed(100); Number(1).toFixed(101);
}, "toFixed() digits argument must be between 0 and 20", RangeError); }, "toFixed() digits argument must be between 0 and 100", RangeError);
test(function() { test(function() {
Number(1).toExponential(100); Number(1).toExponential(101);
}, "toExponential() argument must be between 0 and 20", RangeError); }, "toExponential() argument must be between 0 and 100", RangeError);
// kStackOverflow // kStackOverflow
test(function() { test(function() {
...@@ -441,8 +441,8 @@ test(function() { ...@@ -441,8 +441,8 @@ test(function() {
// kToPrecisionFormatRange // kToPrecisionFormatRange
test(function() { test(function() {
Number(1).toPrecision(100); Number(1).toPrecision(101);
}, "toPrecision() argument must be between 1 and 21", RangeError); }, "toPrecision() argument must be between 1 and 100", RangeError);
// kToPrecisionFormatRange // kToPrecisionFormatRange
test(function() { test(function() {
......
...@@ -301,9 +301,6 @@ ...@@ -301,9 +301,6 @@
# returned via the indirect 'arguments' property accessor. # returned via the indirect 'arguments' property accessor.
'js1_4/Functions/function-001': [FAIL_OK], 'js1_4/Functions/function-001': [FAIL_OK],
# toPrecision argument restricted to range 1..21 in JSC/V8 and ECMA-262
'js1_5/Regress/regress-452346': [FAIL_OK],
# Fail because it calls builtins as functions and do not expect the # Fail because it calls builtins as functions and do not expect the
# builtin to have undefined as the receiver. # builtin to have undefined as the receiver.
'ecma/String/15.5.4.6-2': [FAIL_OK], 'ecma/String/15.5.4.6-2': [FAIL_OK],
......
...@@ -506,11 +506,6 @@ ...@@ -506,11 +506,6 @@
'built-ins/Array/prototype/splice/create-species-length-exceeding-integer-limit': [FAIL], 'built-ins/Array/prototype/splice/create-species-length-exceeding-integer-limit': [FAIL],
'built-ins/Array/prototype/splice/throws-if-integer-limit-exceeded': [SKIP], 'built-ins/Array/prototype/splice/throws-if-integer-limit-exceeded': [SKIP],
# https://bugs.chromium.org/p/v8/issues/detail?id=6539
'built-ins/Number/prototype/toFixed/range': [FAIL],
'built-ins/Number/prototype/toPrecision/range': [FAIL],
'built-ins/Number/prototype/toExponential/range': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=5855 # https://bugs.chromium.org/p/v8/issues/detail?id=5855
'language/expressions/async-generator/named-yield-promise-reject-next': [FAIL], 'language/expressions/async-generator/named-yield-promise-reject-next': [FAIL],
'language/expressions/async-generator/named-yield-promise-reject-next-catch': [FAIL], 'language/expressions/async-generator/named-yield-promise-reject-next-catch': [FAIL],
......
...@@ -86,11 +86,11 @@ PASS Number(-Math.pow(10,21)).toFixed(20) is "-1e+21" ...@@ -86,11 +86,11 @@ PASS Number(-Math.pow(10,21)).toFixed(20) is "-1e+21"
PASS toFixedOrException(2,-1).indexOf('Range') >= 0 is true PASS toFixedOrException(2,-1).indexOf('Range') >= 0 is true
PASS Number(2).toFixed(0) is "2" PASS Number(2).toFixed(0) is "2"
PASS Number(2).toFixed(20) is "2.00000000000000000000" PASS Number(2).toFixed(20) is "2.00000000000000000000"
PASS toFixedOrException(2,21).indexOf('Range') >= 0 is true FAIL toFixedOrException(2,21).indexOf('Range') >= 0 should be true. Was false.
PASS toFixedOrException(-2,-1).indexOf('Range') >= 0 is true PASS toFixedOrException(-2,-1).indexOf('Range') >= 0 is true
PASS Number(-2).toFixed(0) is "-2" PASS Number(-2).toFixed(0) is "-2"
PASS Number(-2).toFixed(20) is "-2.00000000000000000000" PASS Number(-2).toFixed(20) is "-2.00000000000000000000"
PASS toFixedOrException(-2,21).indexOf('Range') >= 0 is true FAIL toFixedOrException(-2,21).indexOf('Range') >= 0 should be true. Was false.
PASS Number(NaN).toExponential() is "NaN" PASS Number(NaN).toExponential() is "NaN"
PASS Number(Infinity).toExponential() is "Infinity" PASS Number(Infinity).toExponential() is "Infinity"
PASS Number(-Infinity).toExponential() is "-Infinity" PASS Number(-Infinity).toExponential() is "-Infinity"
...@@ -120,7 +120,7 @@ PASS Number(123.456).toExponential(17) is "1.23456000000000003e+2" ...@@ -120,7 +120,7 @@ PASS Number(123.456).toExponential(17) is "1.23456000000000003e+2"
PASS Number(123.456).toExponential(18) is "1.234560000000000031e+2" PASS Number(123.456).toExponential(18) is "1.234560000000000031e+2"
PASS Number(123.456).toExponential(19) is "1.2345600000000000307e+2" PASS Number(123.456).toExponential(19) is "1.2345600000000000307e+2"
PASS Number(123.456).toExponential(20) is "1.23456000000000003070e+2" PASS Number(123.456).toExponential(20) is "1.23456000000000003070e+2"
PASS try { Number(123.456).toExponential(21) } catch (e) { String(e).indexOf('Range') >= 0; } is true FAIL try { Number(123.456).toExponential(21) } catch (e) { String(e).indexOf('Range') >= 0; } should be true (of type boolean). Was 1.234560000000000030695e+2 (of type string).
PASS Number(-123.456).toExponential() is "-1.23456e+2" PASS Number(-123.456).toExponential() is "-1.23456e+2"
PASS try { Number(-123.456).toExponential(-1) } catch (e) { String(e).indexOf('Range') >= 0; } is true PASS try { Number(-123.456).toExponential(-1) } catch (e) { String(e).indexOf('Range') >= 0; } is true
PASS Number(-123.456).toExponential(0) is "-1e+2" PASS Number(-123.456).toExponential(0) is "-1e+2"
...@@ -144,7 +144,7 @@ PASS Number(-123.456).toExponential(17) is "-1.23456000000000003e+2" ...@@ -144,7 +144,7 @@ PASS Number(-123.456).toExponential(17) is "-1.23456000000000003e+2"
PASS Number(-123.456).toExponential(18) is "-1.234560000000000031e+2" PASS Number(-123.456).toExponential(18) is "-1.234560000000000031e+2"
PASS Number(-123.456).toExponential(19) is "-1.2345600000000000307e+2" PASS Number(-123.456).toExponential(19) is "-1.2345600000000000307e+2"
PASS Number(-123.456).toExponential(20) is "-1.23456000000000003070e+2" PASS Number(-123.456).toExponential(20) is "-1.23456000000000003070e+2"
PASS try { Number(-123.456).toExponential(21) } catch (e) { String(e).indexOf('Range') >= 0; } is true FAIL try { Number(-123.456).toExponential(21) } catch (e) { String(e).indexOf('Range') >= 0; } should be true (of type boolean). Was -1.234560000000000030695e+2 (of type string).
PASS Number(.000123456).toExponential() is "1.23456e-4" PASS Number(.000123456).toExponential() is "1.23456e-4"
PASS try { Number(.000123456).toExponential(-1) } catch (e) { String(e).indexOf('Range') >= 0; } is true PASS try { Number(.000123456).toExponential(-1) } catch (e) { String(e).indexOf('Range') >= 0; } is true
PASS Number(.000123456).toExponential(0) is "1e-4" PASS Number(.000123456).toExponential(0) is "1e-4"
...@@ -168,7 +168,7 @@ PASS Number(.000123456).toExponential(17) is "1.23456000000000005e-4" ...@@ -168,7 +168,7 @@ PASS Number(.000123456).toExponential(17) is "1.23456000000000005e-4"
PASS Number(.000123456).toExponential(18) is "1.234560000000000052e-4" PASS Number(.000123456).toExponential(18) is "1.234560000000000052e-4"
PASS Number(.000123456).toExponential(19) is "1.2345600000000000519e-4" PASS Number(.000123456).toExponential(19) is "1.2345600000000000519e-4"
PASS Number(.000123456).toExponential(20) is "1.23456000000000005188e-4" PASS Number(.000123456).toExponential(20) is "1.23456000000000005188e-4"
PASS try { Number(.000123456).toExponential(21) } catch (e) { String(e).indexOf('Range') >= 0; } is true FAIL try { Number(.000123456).toExponential(21) } catch (e) { String(e).indexOf('Range') >= 0; } should be true (of type boolean). Was 1.234560000000000051876e-4 (of type string).
PASS Number(-.000123456).toExponential() is "-1.23456e-4" PASS Number(-.000123456).toExponential() is "-1.23456e-4"
PASS try { Number(-.000123456).toExponential(-1) } catch (e) { String(e).indexOf('Range') >= 0; } is true PASS try { Number(-.000123456).toExponential(-1) } catch (e) { String(e).indexOf('Range') >= 0; } is true
PASS Number(-.000123456).toExponential(0) is "-1e-4" PASS Number(-.000123456).toExponential(0) is "-1e-4"
...@@ -192,7 +192,7 @@ PASS Number(-.000123456).toExponential(17) is "-1.23456000000000005e-4" ...@@ -192,7 +192,7 @@ PASS Number(-.000123456).toExponential(17) is "-1.23456000000000005e-4"
PASS Number(-.000123456).toExponential(18) is "-1.234560000000000052e-4" PASS Number(-.000123456).toExponential(18) is "-1.234560000000000052e-4"
PASS Number(-.000123456).toExponential(19) is "-1.2345600000000000519e-4" PASS Number(-.000123456).toExponential(19) is "-1.2345600000000000519e-4"
PASS Number(-.000123456).toExponential(20) is "-1.23456000000000005188e-4" PASS Number(-.000123456).toExponential(20) is "-1.23456000000000005188e-4"
PASS try { Number(-.000123456).toExponential(21) } catch (e) { String(e).indexOf('Range') >= 0; } is true FAIL try { Number(-.000123456).toExponential(21) } catch (e) { String(e).indexOf('Range') >= 0; } should be true (of type boolean). Was -1.234560000000000051876e-4 (of type string).
PASS Number(123.4567890123456789012).toExponential() is "1.2345678901234568e+2" PASS Number(123.4567890123456789012).toExponential() is "1.2345678901234568e+2"
PASS try { Number(123.4567890123456789012).toExponential(-1) } catch (e) { String(e).indexOf('Range') >= 0; } is true PASS try { Number(123.4567890123456789012).toExponential(-1) } catch (e) { String(e).indexOf('Range') >= 0; } is true
PASS Number(123.4567890123456789012).toExponential(0) is "1e+2" PASS Number(123.4567890123456789012).toExponential(0) is "1e+2"
...@@ -216,7 +216,7 @@ PASS Number(123.4567890123456789012).toExponential(17) is "1.23456789012345681e+ ...@@ -216,7 +216,7 @@ PASS Number(123.4567890123456789012).toExponential(17) is "1.23456789012345681e+
PASS Number(123.4567890123456789012).toExponential(18) is "1.234567890123456806e+2" PASS Number(123.4567890123456789012).toExponential(18) is "1.234567890123456806e+2"
PASS Number(123.4567890123456789012).toExponential(19) is "1.2345678901234568059e+2" PASS Number(123.4567890123456789012).toExponential(19) is "1.2345678901234568059e+2"
PASS Number(123.4567890123456789012).toExponential(20) is "1.23456789012345680590e+2" PASS Number(123.4567890123456789012).toExponential(20) is "1.23456789012345680590e+2"
PASS try { Number(123.4567890123456789012).toExponential(21) } catch (e) { String(e).indexOf('Range') >= 0; } is true FAIL try { Number(123.4567890123456789012).toExponential(21) } catch (e) { String(e).indexOf('Range') >= 0; } should be true (of type boolean). Was 1.234567890123456805895e+2 (of type string).
PASS Number(-123.4567890123456789012).toExponential() is "-1.2345678901234568e+2" PASS Number(-123.4567890123456789012).toExponential() is "-1.2345678901234568e+2"
PASS try { Number(-123.4567890123456789012).toExponential(-1) } catch (e) { String(e).indexOf('Range') >= 0; } is true PASS try { Number(-123.4567890123456789012).toExponential(-1) } catch (e) { String(e).indexOf('Range') >= 0; } is true
PASS Number(-123.4567890123456789012).toExponential(0) is "-1e+2" PASS Number(-123.4567890123456789012).toExponential(0) is "-1e+2"
...@@ -240,7 +240,7 @@ PASS Number(-123.4567890123456789012).toExponential(17) is "-1.23456789012345681 ...@@ -240,7 +240,7 @@ PASS Number(-123.4567890123456789012).toExponential(17) is "-1.23456789012345681
PASS Number(-123.4567890123456789012).toExponential(18) is "-1.234567890123456806e+2" PASS Number(-123.4567890123456789012).toExponential(18) is "-1.234567890123456806e+2"
PASS Number(-123.4567890123456789012).toExponential(19) is "-1.2345678901234568059e+2" PASS Number(-123.4567890123456789012).toExponential(19) is "-1.2345678901234568059e+2"
PASS Number(-123.4567890123456789012).toExponential(20) is "-1.23456789012345680590e+2" PASS Number(-123.4567890123456789012).toExponential(20) is "-1.23456789012345680590e+2"
PASS try { Number(-123.4567890123456789012).toExponential(21) } catch (e) { String(e).indexOf('Range') >= 0; } is true FAIL try { Number(-123.4567890123456789012).toExponential(21) } catch (e) { String(e).indexOf('Range') >= 0; } should be true (of type boolean). Was -1.234567890123456805895e+2 (of type string).
PASS Number(.0000000000000000000001).toExponential() is "1e-22" PASS Number(.0000000000000000000001).toExponential() is "1e-22"
PASS Number(.0000000000000000000012).toExponential() is "1.2e-21" PASS Number(.0000000000000000000012).toExponential() is "1.2e-21"
PASS Number(.0000000000000000000123).toExponential() is "1.23e-20" PASS Number(.0000000000000000000123).toExponential() is "1.23e-20"
...@@ -331,7 +331,7 @@ PASS try { Number(1).toPrecision(-1); } catch (e) { String(e).indexOf('Range') > ...@@ -331,7 +331,7 @@ PASS try { Number(1).toPrecision(-1); } catch (e) { String(e).indexOf('Range') >
PASS try { Number(1).toPrecision(0); } catch (e) { String(e).indexOf('Range') >= 0; } is true PASS try { Number(1).toPrecision(0); } catch (e) { String(e).indexOf('Range') >= 0; } is true
PASS try { Number(1).toPrecision(1); } catch (e) { String(e); } is "1" PASS try { Number(1).toPrecision(1); } catch (e) { String(e); } is "1"
PASS try { Number(1).toPrecision(21); } catch (e) { String(e); } is "1.00000000000000000000" PASS try { Number(1).toPrecision(21); } catch (e) { String(e); } is "1.00000000000000000000"
PASS try { Number(1).toPrecision(22); } catch (e) { String(e).indexOf('Range') >= 0; } is true FAIL try { Number(1).toPrecision(22); } catch (e) { String(e).indexOf('Range') >= 0; } should be true (of type boolean). Was 1.000000000000000000000 (of type string).
PASS Number(NaN).toPrecision() is "NaN" PASS Number(NaN).toPrecision() is "NaN"
PASS Number(NaN).toPrecision(1) is "NaN" PASS Number(NaN).toPrecision(1) is "NaN"
PASS Number(Infinity).toPrecision() is "Infinity" PASS Number(Infinity).toPrecision() is "Infinity"
......
...@@ -65,16 +65,16 @@ PASS (1234.567).toFixed(2) is "1234.57" ...@@ -65,16 +65,16 @@ PASS (1234.567).toFixed(2) is "1234.57"
PASS (1234.567).toFixed(2.9) is "1234.57" PASS (1234.567).toFixed(2.9) is "1234.57"
PASS (1234.567).toFixed(5) is "1234.56700" PASS (1234.567).toFixed(5) is "1234.56700"
PASS (1234.567).toFixed(20) is "1234.56700000000000727596" PASS (1234.567).toFixed(20) is "1234.56700000000000727596"
PASS (1234.567).toFixed(21) threw exception RangeError: toFixed() digits argument must be between 0 and 20. FAIL (1234.567).toFixed(21) should throw an exception. Was 1234.567000000000007275958.
PASS (1234.567).toFixed(100) threw exception RangeError: toFixed() digits argument must be between 0 and 20. FAIL (1234.567).toFixed(100) should throw an exception. Was 1234.5670000000000072759576141834259033203125000000000000000000000000000000000000000000000000000000000000.
PASS (1234.567).toFixed(101) threw exception RangeError: toFixed() digits argument must be between 0 and 20. PASS (1234.567).toFixed(101) threw exception RangeError: toFixed() digits argument must be between 0 and 100.
PASS (1234.567).toFixed(-1) threw exception RangeError: toFixed() digits argument must be between 0 and 20. PASS (1234.567).toFixed(-1) threw exception RangeError: toFixed() digits argument must be between 0 and 100.
PASS (1234.567).toFixed(-4) threw exception RangeError: toFixed() digits argument must be between 0 and 20. PASS (1234.567).toFixed(-4) threw exception RangeError: toFixed() digits argument must be between 0 and 100.
PASS (1234.567).toFixed(-5) threw exception RangeError: toFixed() digits argument must be between 0 and 20. PASS (1234.567).toFixed(-5) threw exception RangeError: toFixed() digits argument must be between 0 and 100.
PASS (1234.567).toFixed(-20) threw exception RangeError: toFixed() digits argument must be between 0 and 20. PASS (1234.567).toFixed(-20) threw exception RangeError: toFixed() digits argument must be between 0 and 100.
PASS (1234.567).toFixed(-21) threw exception RangeError: toFixed() digits argument must be between 0 and 20. PASS (1234.567).toFixed(-21) threw exception RangeError: toFixed() digits argument must be between 0 and 100.
PASS (1234.567).toFixed(posInf) threw exception RangeError: toFixed() digits argument must be between 0 and 20. PASS (1234.567).toFixed(posInf) threw exception RangeError: toFixed() digits argument must be between 0 and 100.
PASS (1234.567).toFixed(negInf) threw exception RangeError: toFixed() digits argument must be between 0 and 20. PASS (1234.567).toFixed(negInf) threw exception RangeError: toFixed() digits argument must be between 0 and 100.
PASS posInf.toFixed() is "Infinity" PASS posInf.toFixed() is "Infinity"
PASS negInf.toFixed() is "-Infinity" PASS negInf.toFixed() is "-Infinity"
PASS nan.toFixed() is "NaN" PASS nan.toFixed() is "NaN"
......
...@@ -34,11 +34,11 @@ PASS (-0.0).toPrecision(4) is "0.000" ...@@ -34,11 +34,11 @@ PASS (-0.0).toPrecision(4) is "0.000"
PASS (0.0).toPrecision() is "0" PASS (0.0).toPrecision() is "0"
PASS (-0.0).toPrecision() is "0" PASS (-0.0).toPrecision() is "0"
PASS (1234.567).toPrecision() is "1234.567" PASS (1234.567).toPrecision() is "1234.567"
PASS (1234.567).toPrecision(0) threw exception RangeError: toPrecision() argument must be between 1 and 21. PASS (1234.567).toPrecision(0) threw exception RangeError: toPrecision() argument must be between 1 and 100.
PASS (1234.567).toPrecision(null) threw exception RangeError: toPrecision() argument must be between 1 and 21. PASS (1234.567).toPrecision(null) threw exception RangeError: toPrecision() argument must be between 1 and 100.
PASS (1234.567).toPrecision(false) threw exception RangeError: toPrecision() argument must be between 1 and 21. PASS (1234.567).toPrecision(false) threw exception RangeError: toPrecision() argument must be between 1 and 100.
PASS (1234.567).toPrecision('foo') threw exception RangeError: toPrecision() argument must be between 1 and 21. PASS (1234.567).toPrecision('foo') threw exception RangeError: toPrecision() argument must be between 1 and 100.
PASS (1234.567).toPrecision(-1) threw exception RangeError: toPrecision() argument must be between 1 and 21. PASS (1234.567).toPrecision(-1) threw exception RangeError: toPrecision() argument must be between 1 and 100.
PASS (1234.567).toPrecision(1) is "1e+3" PASS (1234.567).toPrecision(1) is "1e+3"
PASS (1234.567).toPrecision(true) is "1e+3" PASS (1234.567).toPrecision(true) is "1e+3"
PASS (1234.567).toPrecision('1') is "1e+3" PASS (1234.567).toPrecision('1') is "1e+3"
...@@ -46,12 +46,12 @@ PASS (1234.567).toPrecision(2) is "1.2e+3" ...@@ -46,12 +46,12 @@ PASS (1234.567).toPrecision(2) is "1.2e+3"
PASS (1234.567).toPrecision(2.9) is "1.2e+3" PASS (1234.567).toPrecision(2.9) is "1.2e+3"
PASS (1234.567).toPrecision(5) is "1234.6" PASS (1234.567).toPrecision(5) is "1234.6"
PASS (1234.567).toPrecision(21) is "1234.56700000000000728" PASS (1234.567).toPrecision(21) is "1234.56700000000000728"
PASS (1234.567).toPrecision(22) threw exception RangeError: toPrecision() argument must be between 1 and 21. FAIL (1234.567).toPrecision(22) should throw an exception. Was 1234.567000000000007276.
PASS (1234.567).toPrecision(100) threw exception RangeError: toPrecision() argument must be between 1 and 21. FAIL (1234.567).toPrecision(100) should throw an exception. Was 1234.567000000000007275957614183425903320312500000000000000000000000000000000000000000000000000000000.
PASS (1234.567).toPrecision(101) threw exception RangeError: toPrecision() argument must be between 1 and 21. PASS (1234.567).toPrecision(101) threw exception RangeError: toPrecision() argument must be between 1 and 100.
PASS (1234.567).toPrecision(posInf) threw exception RangeError: toPrecision() argument must be between 1 and 21. PASS (1234.567).toPrecision(posInf) threw exception RangeError: toPrecision() argument must be between 1 and 100.
PASS (1234.567).toPrecision(negInf) threw exception RangeError: toPrecision() argument must be between 1 and 21. PASS (1234.567).toPrecision(negInf) threw exception RangeError: toPrecision() argument must be between 1 and 100.
PASS (1234.567).toPrecision(nan) threw exception RangeError: toPrecision() argument must be between 1 and 21. PASS (1234.567).toPrecision(nan) threw exception RangeError: toPrecision() argument must be between 1 and 100.
PASS posInf.toPrecision() is "Infinity" PASS posInf.toPrecision() is "Infinity"
PASS negInf.toPrecision() is "-Infinity" PASS negInf.toPrecision() is "-Infinity"
PASS nan.toPrecision() is "NaN" PASS nan.toPrecision() is "NaN"
......
...@@ -40,12 +40,12 @@ PASS (123.456).toExponential(3) is "1.235e+2" ...@@ -40,12 +40,12 @@ PASS (123.456).toExponential(3) is "1.235e+2"
PASS (123.456).toExponential(5) is "1.23456e+2" PASS (123.456).toExponential(5) is "1.23456e+2"
PASS (123.456).toExponential(6) is "1.234560e+2" PASS (123.456).toExponential(6) is "1.234560e+2"
PASS (123.456).toExponential(20) is "1.23456000000000003070e+2" PASS (123.456).toExponential(20) is "1.23456000000000003070e+2"
PASS (123.456).toExponential(21) threw exception RangeError: toExponential() argument must be between 0 and 20. FAIL (123.456).toExponential(21) should throw an exception. Was 1.234560000000000030695e+2.
PASS (123.456).toExponential(100) threw exception RangeError: toExponential() argument must be between 0 and 20. FAIL (123.456).toExponential(100) should throw an exception. Was 1.2345600000000000306954461848363280296325683593750000000000000000000000000000000000000000000000000000e+2.
PASS (123.456).toExponential(101) threw exception RangeError: toExponential() argument must be between 0 and 20. PASS (123.456).toExponential(101) threw exception RangeError: toExponential() argument must be between 0 and 100.
PASS (123.456).toExponential(-1) threw exception RangeError: toExponential() argument must be between 0 and 20. PASS (123.456).toExponential(-1) threw exception RangeError: toExponential() argument must be between 0 and 100.
PASS (1234.567).toExponential(posInf) threw exception RangeError: toExponential() argument must be between 0 and 20. PASS (1234.567).toExponential(posInf) threw exception RangeError: toExponential() argument must be between 0 and 100.
PASS (1234.567).toExponential(negInf) threw exception RangeError: toExponential() argument must be between 0 and 20. PASS (1234.567).toExponential(negInf) threw exception RangeError: toExponential() argument must be between 0 and 100.
PASS posInf.toExponential() is "Infinity" PASS posInf.toExponential() is "Infinity"
PASS negInf.toExponential() is "-Infinity" PASS negInf.toExponential() is "-Infinity"
PASS nan.toExponential() is "NaN" PASS nan.toExponential() is "NaN"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment