I found in a previous question that Math.pow(0, 0) === 1
returns true
.
In the documentation we find the following rules for x^y
:
- If y is NaN, the result is NaN.
- If y is +0, the result is 1, even if x is NaN.
- If y is −0, the result is 1, even if x is NaN.
- If x is NaN and y is nonzero, the result is NaN.
- If abs(x)>1 and y is +∞, the result is +∞.
- If abs(x)>1 and y is −∞, the result is +0.
- If abs(x)==1 and y is +∞, the result is NaN.
- If abs(x)==1 and y is −∞, the result is NaN.
- If abs(x)<1 and y is +∞, the result is +0.
- If abs(x)<1 and y is −∞, the result is +∞.
- If x is +∞ and y>0, the result is +∞.
- If x is +∞ and y<0, the result is +0.
- If x is −∞ and y>0 and y is an odd integer, the result is −∞.
- If x is −∞ and y>0 and y is not an odd integer, the result is +∞.
- If x is −∞ and y<0 and y is an odd integer, the result is −0.
- If x is −∞ and y<0 and y is not an odd integer, the result is +0.
- If x is +0 and y>0, the result is +0.
- If x is +0 and y<0, the result is +∞.
- If x is −0 and y>0 and y is an odd integer, the result is −0.
- If x is −0 and y>0 and y is not an odd integer, the result is +0.
- If x is −0 and y<0 and y is an odd integer, the result is −∞.
- If x is −0 and y<0 and y is not an odd integer, the result is +∞.
- If x<0 and x is finite and y is finite and y is not an integer, the result is NaN.
What is interesting is that for any value of x
the returned value is 1
. Can we find any value for x
for what Math.pow(x, 0)
returns a value that is NOT 1
?
I tried the following in the NodeJS shell, but I guess it's the same result in the browser console:
> Math.pow(undefined, 0)
1
> Math.pow(Date(), 0)
1
> Math.pow("asd", 0)
1
> Math.pow(function () {}, 0)
1
> Math.pow(function () { return 3}, 0)
1
> Math.pow([], 0)
1
> Math.pow(null, 0)
1
Maybe we find a JS trick that does this, like in the x === x // false
(where isNaN(x) === false
) case.
Just to clarify: y
will be always 0
. Only x
is changing.
I found in a previous question that Math.pow(0, 0) === 1
returns true
.
In the documentation we find the following rules for x^y
:
- If y is NaN, the result is NaN.
- If y is +0, the result is 1, even if x is NaN.
- If y is −0, the result is 1, even if x is NaN.
- If x is NaN and y is nonzero, the result is NaN.
- If abs(x)>1 and y is +∞, the result is +∞.
- If abs(x)>1 and y is −∞, the result is +0.
- If abs(x)==1 and y is +∞, the result is NaN.
- If abs(x)==1 and y is −∞, the result is NaN.
- If abs(x)<1 and y is +∞, the result is +0.
- If abs(x)<1 and y is −∞, the result is +∞.
- If x is +∞ and y>0, the result is +∞.
- If x is +∞ and y<0, the result is +0.
- If x is −∞ and y>0 and y is an odd integer, the result is −∞.
- If x is −∞ and y>0 and y is not an odd integer, the result is +∞.
- If x is −∞ and y<0 and y is an odd integer, the result is −0.
- If x is −∞ and y<0 and y is not an odd integer, the result is +0.
- If x is +0 and y>0, the result is +0.
- If x is +0 and y<0, the result is +∞.
- If x is −0 and y>0 and y is an odd integer, the result is −0.
- If x is −0 and y>0 and y is not an odd integer, the result is +0.
- If x is −0 and y<0 and y is an odd integer, the result is −∞.
- If x is −0 and y<0 and y is not an odd integer, the result is +∞.
- If x<0 and x is finite and y is finite and y is not an integer, the result is NaN.
What is interesting is that for any value of x
the returned value is 1
. Can we find any value for x
for what Math.pow(x, 0)
returns a value that is NOT 1
?
I tried the following in the NodeJS shell, but I guess it's the same result in the browser console:
> Math.pow(undefined, 0)
1
> Math.pow(Date(), 0)
1
> Math.pow("asd", 0)
1
> Math.pow(function () {}, 0)
1
> Math.pow(function () { return 3}, 0)
1
> Math.pow([], 0)
1
> Math.pow(null, 0)
1
Maybe we find a JS trick that does this, like in the x === x // false
(where isNaN(x) === false
) case.
Just to clarify: y
will be always 0
. Only x
is changing.
- 4 Just one question: why do you need it? – VisioN Commented Nov 14, 2013 at 11:56
- 2 @VisioN To satisfy my curiosity...? Maybe. – Ionică Bizău Commented Nov 14, 2013 at 11:57
-
1
Mathematically speaking, zero is the only x for which
x pow 0
is not 0, but undefined. Not the JavaScriptundefined
, it's just a mathematical rule saying that there's no logic in0 pow 0
so it's an undefined result. It could be both anything and nothing. Read this: math.stackexchange./questions/11150/… – Sergiu Paraschiv Commented Nov 14, 2013 at 11:59 - 1 Doesn't the documentation you pointed out mention pretty clearly that for y = 0 or y=-0, the result is 1, no matter what? – Tibos Commented Nov 14, 2013 at 12:00
-
1
@イオニカ ビザウ I did not say what the result of JavaScript's
Math.pow
is, I just stated what's the mathematical philosophy behind it. – Sergiu Paraschiv Commented Nov 14, 2013 at 12:04
4 Answers
Reset to default 8Your copy/paste from the documentation includes the requirement:
- If y is +0, the result is 1, even if x is NaN
So it would seem the answer to your question is "No"
No, there is never any situation where the result will not be run. The definition of the function states that:
- If y is NaN, the result is NaN.
- If y is +0, the result is 1, even if x is NaN.
- If y is -0, the result is 1, even if x is NaN.
All arguments are coerced to numeric type before being run, so therefore no matter what it will be 1. If multiple results are applicable, the first one in order that is applicable is the result returned, which in this case is 1
.
As you have said that y is 0, it is therefore not NaN, and will not return NaN as a result.
ES5 §15.8.2:
Each of the following Math object functions applies the ToNumber abstract operator to each of its arguments (in left-to-right order if there is more than one) and then performs a putation on the resulting Number value(s).
Any arguments which aren't numbers (or strings that satisfy the format of a number) will be either coerced to 0 (for null
, false
and ""
), 1 (for true
) or NaN (anything else).
Right, since you are using node.js, which runs V8, lets have a look at the sources.
Function Math.pow
is defined in math.js
and states:
function MathPow(x, y) {
return %_MathPow(TO_NUMBER_INLINE(x), TO_NUMBER_INLINE(y));
}
Macros TO_NUMBER_INLINE
is used to cast any type to numeric value. Hence in the _MathPow
operation we have numbers as arguments.
Lets move forward to hydrogen
, which has implementation of MathPow
call that refers to HPower
instruction in hydrogen-instructions
. The latter calculates the power using power_helper(c_left->DoubleValue(), c_right->DoubleValue())
: the method defined in assembler
. Here we finally have the logic of the calculations:
double power_helper(double x, double y) {
int y_int = static_cast<int>(y);
if (y == y_int) {
return power_double_int(x, y_int); // Returns 1 if exponent is 0.
}
// ...
}
The ment (copied from the sources) says everything, and there is even no need to inspect power_double_int
defined in the same file to say that every value passed to Math.pow
as the first argument with y == 0
will return 1
.
To say that definitely lets check power_double_int
:
double power_double_int(double x, int y) {
double m = (y < 0) ? 1 / x : x;
unsigned n = (y < 0) ? -y : y;
double p = 1;
while (n != 0) {
if ((n & 1) != 0) p *= m;
m *= m;
if ((n & 2) != 0) p *= m;
m *= m;
n >>= 2;
}
return p;
}
From the above, n
will always be 0
, so while
loop will never run, returning p = 1
unchanged.
The first three steps of the algorithm according to the ES5 spec are as follows:
- If y is NaN, the result is NaN.
- If y is +0, the result is 1, even if x is NaN.
- If y is −0, the result is 1, even if x is NaN.
If you were writing an implementation of the ES5 standard, your code would probably look something like this:
function pow(x, y) {
if (isNaN(y)) return NaN;
if (y === 0) return 1;
// ... follow the other rules
}
There is not going to be any value of x
that will cause it to return anything other than 1
when y === 0
.