最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Is there any `x` value where Math.pow(x, 0) is NOT 1? - Stack Overflow

programmeradmin0浏览0评论

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.

Share Improve this question edited May 23, 2017 at 12:13 CommunityBot 11 silver badge asked Nov 14, 2013 at 11:54 Ionică BizăuIonică Bizău 114k94 gold badges307 silver badges487 bronze badges 12
  • 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 JavaScript undefined, it's just a mathematical rule saying that there's no logic in 0 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
 |  Show 7 more ments

4 Answers 4

Reset to default 8

Your 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.

发布评论

评论列表(0)

  1. 暂无评论