[math] Fix Math.hypot to properly call ToNumber on all arguments.
The spec requires all Math functions to first call ToNumber on all arguments before doing any other observable operation. So early return in case of Infinity is not valid. Drive-by-fix: Remove the use of %_Arguments / %_ArgumentsLength and use (strict) arguments instead of allocating a temporary InternalArray explicitly. R=yangguo@chromium.org Review URL: https://codereview.chromium.org/1669773002 Cr-Commit-Position: refs/heads/master@{#33717}
This commit is contained in:
parent
db74cccf8a
commit
264fa75e52
@ -164,17 +164,14 @@ function MathHypot(x, y) { // Function length is 2.
|
||||
// We may want to introduce fast paths for two arguments and when
|
||||
// normalization to avoid overflow is not necessary. For now, we
|
||||
// simply assume the general case.
|
||||
var length = %_ArgumentsLength();
|
||||
var args = new InternalArray(length);
|
||||
var length = arguments.length;
|
||||
var max = 0;
|
||||
for (var i = 0; i < length; i++) {
|
||||
var n = %_Arguments(i);
|
||||
n = TO_NUMBER(n);
|
||||
if (n === INFINITY || n === -INFINITY) return INFINITY;
|
||||
n = MathAbs(n);
|
||||
var n = MathAbs(arguments[i]);
|
||||
if (n > max) max = n;
|
||||
args[i] = n;
|
||||
arguments[i] = n;
|
||||
}
|
||||
if (max === INFINITY) return INFINITY;
|
||||
|
||||
// Kahan summation to avoid rounding errors.
|
||||
// Normalize the numbers to the largest one to avoid overflow.
|
||||
@ -182,7 +179,7 @@ function MathHypot(x, y) { // Function length is 2.
|
||||
var sum = 0;
|
||||
var compensation = 0;
|
||||
for (var i = 0; i < length; i++) {
|
||||
var n = args[i] / max;
|
||||
var n = arguments[i] / max;
|
||||
var summand = n * n - compensation;
|
||||
var preliminary = sum + summand;
|
||||
compensation = (preliminary - sum) - summand;
|
||||
|
@ -56,6 +56,13 @@ x = "";
|
||||
assertEquals(1, Math.pow(v, w));
|
||||
assertEquals("hestfisk", x, "pow");
|
||||
|
||||
x = "";
|
||||
var a = {valueOf: function() { x += "hest"; return 1/0; }};
|
||||
var b = {valueOf: function() { x += "fisk"; return 1}};
|
||||
assertEquals(1/0, Math.hypot(a, b));
|
||||
assertEquals("hestfisk", x, "hypot");
|
||||
|
||||
|
||||
var year = { valueOf: function() { x += 1; return 2007; } };
|
||||
var month = { valueOf: function() { x += 2; return 2; } };
|
||||
var date = { valueOf: function() { x += 3; return 4; } };
|
||||
|
Loading…
Reference in New Issue
Block a user