为什么Math.pow(0,0)=== 1?

时间:2013-11-13 14:12:29

标签: javascript c++ language-agnostic pow

我们都知道0 0 是不确定的。

javascript 表示:

Math.pow(0, 0) === 1 // true

C ++ 说同样的事情:

pow(0, 0) == 1 // true

为什么?

我知道:

>Math.pow(0.001, 0.001)
0.9931160484209338

但为什么Math.pow(0, 0)不会抛出任何错误?或者NaN可能比1好。

9 个答案:

答案 0 :(得分:78)

在C ++ The result of pow(0, 0) 中,结果基本上是实现定义的行为,因为在数学上我们有一个矛盾的情况,其中N^0应始终为1但{{1}对于0^N0应始终为N > 0,因此您对此结果也不应有数学上的期望。这篇Wolfram Alpha论坛帖子详细介绍了一些内容。

尽管pow(0,0)导致1对于许多应用程序非常有用,但在 IEC 60559浮点运算支持的部分中 Rationale for International Standard—Programming Languages—C状态仍然有用:< / p>

  

通常,C99会避免使用数值有用的NaN结果。 [...] pow(∞,0)和pow(0,0)的结果都是1,因为有些应用程序可以利用这个定义。例如,如果x(p)和y(p)是在p = a时变为零的任何解析函数,则当p接近时,等于exp(y * log(x))的pow(x,y)接近1一个。

更新C ++

正如leemes正确指出我最初链接到 pow pow 的引用,而non-complex版本声称它是域错误 draft C++ standard回到draft C standard C99 C11 7.12.7.4 部分函数 2 表示(强调我的):

  

[...]如果x为零且y为零,则可能发生域错误。[...]

据我所知,这种行为是unspecified behavior绕回一段7.12.1 错误条件的处理说:

  

[...]如果输入参数在域外,则会发生域错误   定义了数学函数。[...]在域错误中,函数返回一个实现定义的值;如果是整数表达式math_errhandling&amp; MATH_ERRNO非零,整数表达式errno获取值EDOM; [...]

因此,如果存在域错误,那么这将是实现定义的行为,但在最新版本的gccclangerrno的值为0,因此这些编译器不是域错误

更新Javascript

对于 Javascript 15.8 中的ECMAScript® Language Specification {em> x> y下的15.8.2.13 数据对象 在其他条件中表示:

  

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

答案 1 :(得分:35)

In JavaScript Math.pow is defined as follows

  
      
  • 如果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。
  •   

强调我的

作为一般规则,任何语言的本机函数都应按照语言规范中的描述进行操作。有时,这包括明确的“未定义行为”,由实现者决定结果应该是什么,但这不是未定义行为的情况。

答案 2 :(得分:16)

将其定义为10或将其undefined保留为惯例。由于以下定义,定义pow(0,0)广泛传播:

mathematical power definition


ECMA-Script文档说明了以下pow(x,y)

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

[http://www.ecma-international.org/ecma-262/5.1/#sec-15.8.2.13]

答案 3 :(得分:14)

根据维基百科:

  

在大多数不涉及指数连续性的设置中,将0 0 解释为1简化了公式,并且无需定理中的特殊情况。

有几种可能的方法可以对每个0**0的利弊进行处理(请参阅Wikipedia进行扩展讨论)。

IEEE 754-2008浮点标准推荐三种不同的功能:

  • pow0**0视为1。这是最早定义的版本。如果幂是精确整数,则结果与pown相同,否则结果与powr相同(除了一些例外情况)。
  • pown将0 ** 0视为1.功率必须是精确整数。该值定义为负基数;例如,pown(−3,5)−243
  • powr将0 ** 0视为NaN(非数字 - 未定义)。对于像powr(−3,2)这样基数小于零的情况,该值也是NaN。该值由exp(power'×log(base))定义。

答案 4 :(得分:6)

Donald Knuth

1992年,我们通过以下方式解决了这场辩论:

enter image description here

在他的论文Two Notes on Notation中进一步详细说明了。

基本上,虽然对于所有函数f(x)/g(x)f(x),我们没有g(x)的限制,但它仍然使组合数更加简单,以定义{{1}然后,只需在需要考虑0^0=1等函数的少数几个地方制作特殊情况,这无论如何都很奇怪。毕竟0^x更频繁出现。

我对这个主题的最佳讨论(Knuth论文除外)是:

答案 5 :(得分:5)

如果您想知道f(a)f无法直接计算a时应该向f提供什么值,那么xa的限制为x^y 1}}倾向于1

如果是x,当y0倾向于x^x时,通常的限制会趋向于1,尤其是x倾向于0当{{1}}倾向于{{1}}时,{{1}}。

请参阅http://www.math.hmc.edu/funfacts/ffiles/10005.3-5.shtml

答案 6 :(得分:5)

C语言定义说(7.12.7.4/2):

  

如果x为零且y为零,则可能发生域错误。

它还说(7.12.1 / 2):

  

在域错误上,该函数返回一个实现定义的值;如果是整数表达式math_errhandling&amp; MATH_ERRNO非零,整数表达式errno获取值EDOM;如果是整数表达式math_errhandling&amp; MATH_ERREXCEPT非零,引发''无效''浮点异常。

默认情况下,math_errhandling的值为MATH_ERRNO,因此请检查errno中的值EDOM

答案 7 :(得分:0)

我想不同意之前的一些答案'断言这是一个约定或方便的问题(涵盖各种定理的一些特殊情况等)0 ^ 0被定义为1而不是0。

指数实际上并不适合我们的其他数学符号,因此我们所学的定义留下了混淆的空间。接近它的一种稍微不同的方式是说a ^ b(或exp(a,b),如果你愿意的话)返回值乘法等价乘以其他东西 a,重复b次。

当我们将5乘以4,2次时,得到80.我们将乘以5乘以16.所以4 ^ 2 = 16。

当你将14乘以0,0次时,我们留下14.我们将它乘以1.因此,0 ^ 0 = 1.

这种思路也可能有助于澄清消极和分数指数。 4 ^( - 2)是第16,因为'负乘法'是除法 - 我们除以4两次。

a ^(1/2)是根(a),因为乘以a的根是乘法工作的一半乘以它自己 - 你必须做两次乘以4 = 4 ^ 1 =(4 ^(1/2))^ 2

答案 8 :(得分:0)

为了理解你需要解决微积分:

enter image description here

使用泰勒系列将x^x扩展到零左右,我们得到:

enter image description here

因此,要了解x为零时的限制, 我们需要找出第二个词x log(x)发生了什么,因为其他词与x log(x)的某些词汇成正比。

我们需要使用转换:

enter image description here

现在,在转换之后,我们可以使用L'Hôpital's rule,其中声明:

enter image description here

区分我们得到的转变:

enter image description here

因此,当x接近0时,我们计算出术语log(x)*x接近0。 很容易看出其他连续的术语也接近零,甚至比第二学期更快。

因此,在x=0点,系列变为1 + 0 + 0 + 0 + ...,因此等于1.