【问题标题】:Is there any `x` value where Math.pow(x, 0) is NOT 1?是否存在 Math.pow(x, 0) 不是 1 的任何“x”值?
【发布时间】:2013-11-14 11:54:12
【问题描述】:

我在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)
  • 如果 abs(x)
  • 如果 x 为 +∞ 且 y>0,则结果为 +∞。
  • 如果 x 为 +∞ 且 y
  • 如果 x 为 -∞ 且 y>0 且 y 为奇数,则结果为 -∞。
  • 如果 x 为 −∞ 且 y>0 且 y 不是奇数,则结果为 +∞。
  • 如果 x 为 -∞ 且 y
  • 如果 x 为 −∞ 且 y
  • 如果 x 为 +0 且 y>0,则结果为 +0。
  • 如果 x 为 +0 且 y
  • 如果 x 为 -0 且 y>0 且 y 为奇数,则结果为 -0。
  • 如果 x 为 -0 且 y>0 且 y 不是奇数,则结果为 +0。
  • 如果 x 为 -0 且 y
  • 如果 x 为 -0 且 y
  • 如果 x

有趣的是,对于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 正在改变。

【问题讨论】:

  • 只有一个问题:为什么需要它?
  • @VisioN 为了满足我的好奇心...?也许吧。
  • 从数学上讲,0 是唯一的 x,x pow 0 不是 0,而是未定义的。不是 JavaScript undefined,它只是一个数学规则,表明 0 pow 0 中没有逻辑,所以它是一个未定义的结果。它既可以是任何东西,也可以是任何东西。阅读:math.stackexchange.com/questions/11150/…
  • 您指出的文档不是很清楚地提到对于 y = 0 或 y=-0,无论如何,结果都是 1?
  • @イオニカ ビザウ 我没有说 JavaScript 的 Math.pow 的结果是什么,我只是说明了它背后的数学哲学是什么。

标签: javascript node.js


【解决方案1】:

您从文档中复制/粘贴的内容包括以下要求:

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

所以你的问题的答案似乎是“否”

【讨论】:

  • 这是否意味着对于任何x,结果都是1?我不相信他们会威胁到非数字值......
  • '以下每个 Math 对象函数都将 ToNumber 抽象运算符应用于其每个参数'...
  • If y is +0, the result is 1 对我来说似乎很明确
【解决方案2】:

不,从不在任何情况下都不会运行结果。 definition of the function 声明:

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

所有参数在运行前都被强制转换为数字类型,因此无论它是1。如果多个结果适用,则第一个适用的结果是返回的结果,在这种情况下为@987654323 @。

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

ES5§15.8.2:

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

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

【讨论】:

  • 抱歉,您没有理解问题。 Math.pow(NaN, 0) 是 1。我的问题是我们是否有一个值 Math.pow(ourValue, 0) 不是 1。
  • @イオニカビザウ:我理解你刚才所说的问题。我的回答是,绝不会如此。
【解决方案3】:

对了,既然你使用的是运行 V8 的 node.js,让我们看看sources

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

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

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

让我们继续前进到hydrogen.cc,它实现了MathPow 调用,该调用引用hydrogen-instructions.cc 中的HPower 指令。后者使用power_helper(c_left->DoubleValue(), c_right->DoubleValue()) 计算功率:assembler.cc 中定义的方法。这里我们终于有了计算的逻辑:

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

  // ...
}

评论(从源代码复制)说明了一切,甚至不需要检查同一文件中定义的power_double_int 来说明传递给Math.pow 作为y == 0 的第一个参数的每个值都将返回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 不变。

【讨论】:

  • 这是正确答案!请从power_double_int 函数中发布代码,因为这给出了答案。 unsigned n = (y &lt; 0) ? -y : y;n 设置0 的值,接下来两行我们有while(n != 0) { /* do something */ } return p;,其中p 被初始化为1。因此,对于y === 0,此函数返回1。好!
【解决方案4】:

根据 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 的任何值都不会导致它在y === 0 时返回1 以外的任何值。

【讨论】:

  • 源代码是从哪里提取的?这似乎是正确的答案!
  • 我说“如果你正在编写一个实现......你的代码可能看起来像这样”。这不是来自 JS 引擎的真实代码。
  • @イオニカビザウ:具体实现代码有什么需求?所有浏览器都被指定遵循 ECMAScript 语言规范中给出的不变量——Math.pow() 的所有主要实现的行为与其指定的方式没有任何不同。如果您想要实现的特定代码,那么您的问题根本没有说清楚,而且它的含义相当混乱。
猜你喜欢
  • 2013-01-09
  • 2019-12-04
  • 2022-03-29
  • 1970-01-01
  • 2011-02-10
  • 2016-10-20
  • 1970-01-01
  • 2015-08-09
  • 1970-01-01
相关资源
最近更新 更多