Math.pow(x,0)是否为1时,是否有任何`x`值?

时间:2013-11-14 11:54:12

标签: javascript node.js

我在previous question中找到Math.pow(0, 0) === 1返回true

the documentation中,我们找到x^y的以下规则:

  
      
  • 如果y为NaN,则结果为NaN。
  •   
  • 如果y为+0,则结果为1,即使x为NaN。
  •   
  • 如果y为-0,则结果为1,即使x为NaN。
  •   
  • 如果x是NaN且y非零,则结果为NaN。
  •   
  • 如果abs(x)> 1且y为+∞,则结果为+∞。
  •   
  • 如果abs(x)> 1且y为-∞,则结果为+0。
  •   
  • 如果abs(x)== 1且y为+∞,则结果为NaN。
  •   
  • 如果abs(x)== 1且y为-∞,则结果为NaN。
  •   
  • 如果abs(x)<1且y为+∞,则结果为+0。
  •   
  • 如果abs(x)<1且y为-∞,则结果为+∞。
  •   
  • 如果x为+∞且y> 0,则结​​果为+∞。
  •   
  • 如果x为+∞且y <0,则结果为+0。
  •   
  • 如果x是-∞且y> 0且y是奇数,则结果为-∞。
  •   
  • 如果x为-∞且y> 0且y不是奇数,则结果为+∞。
  •   
  • 如果x为-∞且y <0且y为奇数,则结果为-0。
  •   
  • 如果x为-∞且y <0且y不是奇数,则结果为+0。
  •   
  • 如果x为+0且y> 0,则结​​果为+0。
  •   
  • 如果x为+0且y <0,则结果为+∞。
  •   
  • 如果x是-0且y> 0且y是奇数,则结果为-0。
  •   
  • 如果x是-0且y> 0且y不是奇数,则结果为+0。
  •   
  • 如果x是-0且y <0且y是奇数,则结果为-∞。
  •   
  • 如果x为-0且y <0且y不是奇数,则结果为+∞。
  •   
  • 如果x <0且x是有限的且y是有限的且y不是整数,则结果为NaN。
  •   

有趣的是,对于x的任何值,返回值为1。对于x返回非Math.pow(x, 0)的值,我们能否找到1的任何值?

我在NodeJS shell中尝试了以下内容,但我猜它在浏览器控制台中的结果相同:

> 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

也许我们发现了一个JS技巧,就像在x === x // false (where isNaN(x) === false)情况下一样。


只是为了澄清:y将永远是0。只有x正在发生变化。

4 个答案:

答案 0 :(得分:8)

您在文档中的复制/粘贴包含以下要求:

  
      
  • 如果y为+0,则结果为1,即使x为NaN
  •   

所以看起来你的问题的答案是“不”

答案 1 :(得分:6)

不,从不任何不会运行结果的情况。 definition of the function表示:

  
      
  • 如果y为NaN,则结果为NaN。
  •   
  • 如果y为+0,则结果为1,即使x为NaN。
  •   
  • 如果y为-0,则结果为1,即使x为NaN。
  •   

所有参数在运行之前都被强制为数字类型,因此无论它是什么1.如果多个结果适用,则第一个适用的顺序是返回的结果,在本例中为{{ 1}}。

正如你所说y为0,因此 NaN,因此不会返回NaN。

ES5 §15.8.2

  

以下每个Math对象函数都将ToNumber抽象运算符应用于其每个参数(如果有多个,则按从左到右的顺序),然​​后对生成的Number值执行计算。 / p>

任何不是数字的参数(或满足数字格式的字符串)都将被强制为0(1nullfalse),1(对于"")或NaN(其他任何东西)。

答案 2 :(得分:2)

是的,既然您正在使用运行V8的node.js,那么让我们看一下sources

函数Math.powmath.js中定义并声明:

function MathPow(x, y) {
  return %_MathPow(TO_NUMBER_INLINE(x), TO_NUMBER_INLINE(y));
}

TO_NUMBER_INLINE用于将任何类型转换为数值。因此,在_MathPow操作中,我们将数字作为参数。

让我们前进到hydrogen.cchydrogen-instructions.cc执行MathPow调用,引用assembler.cc中的HPower指令。后者使用power_helper(c_left->DoubleValue(), c_right->DoubleValue())计算功效:power_double_int中定义的方法。在这里,我们最终得到了计算的逻辑:

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

  // ...
}

注释(从源代码中复制)说明了所有内容,甚至不需要检查同一文件中定义的{{3}}来表示传递给Math.pow的每个值作为y == 0的第一个参数{1}}将返回1

要说明确允许检查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;
}

从上面开始,n始终为0,因此while循环永远不会运行,并且p = 1不会更改。

答案 3 :(得分:1)

根据ES5规范的算法的前三个步骤如下:

  
      
  • 如果 y 是NaN,则结果为NaN。
  •   
  • 如果 y 为+0,则结果为1,即使 x 为NaN。
  •   
  • 如果 y 为-0,则结果为1,即使 x 为NaN。
  •   

如果您正在编写ES5标准的实现,那么您的代码可能如下所示:

function pow(x, y) {
    if (isNaN(y)) return NaN;
    if (y === 0) return 1;
    // ... follow the other rules
}

x时,1没有任何价值会导致其返回y === 0以外的任何内容。