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

我们都知道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

在C ++ 中pow(0,0)的结果基本上是实现定义的行为,因为在math上我们有一个矛盾的情况,其中N^0应该总是1但是对于N > 0 0^N应该总是N > 0 ,所以你应该有math上也没有任何期望的结果。 这个Wolfram Alpha论坛post进入了更多的细节。

尽pipe在IEC 60559浮点算术支持的章节中将pow(0,0)1对于许多应用程序是有用的,如国际标准编程语言-C语言的原理 :

通常,C99在数值有用时避开NaN结果。 pow(∞,0)和pow(0,0)的结果都是1,因为有些应用可以利用这个定义。 例如,如果x(p)和y(p)是在p = a时变为零的任何parsing函数,那么等于exp(y * log(x))的pow(x,y)随着p逼近而接近1一个。

更新C ++

正如leemes正确指出的那样,我原来是和pow复杂版本的引用关联的, 而非复杂的版本声称是域错误,所以C ++标准草案会回落到草案C标准中 ,并且在7.12.7.4节中都是C99C11 pow函数2段说( 强调我的 ):

[…]如果x为零且y为零,则可能会出现域错误。

据我所知这意味着这种行为是未指定的行为回绕一点7.12.1 错误条件的处理说:

[…]如果input参数超出定义math函数的域,就会出现域错误[…]在域错误上,函数返回实现定义的值; 如果整数expression式math_errhandling&MATH_ERRNO不为零,则整型expression式errno获取EDOM值; […]

所以如果有一个域错误,那么这将是实现定义的行为,但在最新版本的gccclang中, errno的值是0所以这不是这些编译器的域错误

更新Javascript

对于Javascript , ECMAScript®语言规范第15.8节中 15.8.2.13 pow(x,y)的Math对象说除其他条件:

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

在JavaScript中Math.pow的定义如下 :

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

强调我的

作为一般规则,任何语言的原生函数都应该按照语言规范中的描述进行工作。 有时候,这包括明确的“未定义的行为”,由实施者决定结果应该是什么,然而这不是未定义的行为。

将它定义为0或者将其undefined只是约定。 定义 POW(0,0) 由于以下定义而广泛传播:

数学力量定义


ECMA脚本文档说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 ]

根据维基百科:

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

有几种可能的方法来处理0**0的优点和缺点(见维基百科进行扩展讨论)。

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

  • pow0**0当作1 。 这是最早定义的版本。 如果权力是一个精确的整数,结果与pown相同,否则结果是pown (除了一些例外情况)。
  • pown将0 ** 0视为1.权力必须是一个确切的整数。 该值定义为负数基数; 例如, pown(−3,5)−243
  • powr将0 ** 0视为NaN(Not-a-Number – 未定义)。 对于类似powr(−3,2)情况,这个值也是NaN,其中基数小于零。 该值由exp(power'×log(base))定义。

唐纳德Knuth

这种争论在1992年得到了解决,具体如下:

在这里输入图像说明

在他的论文“ Two Notation on Notation”中进一步讨论了细节。

基本上,尽pipe对于所有函数f(x)g(x) ,我们没有1作为f(x)/g(x)的极限,但它仍然使得组合方法更容易定义0^0=1 ,然后在less数需要考虑0^x函数的地方做一些特殊情况,这些都是奇怪的。 毕竟x^0经常出现。

我所知道的关于这个主题的一些最好的讨论(Knuth论文除外)是:

当你想知道你应该给f(a)什么值,当f不能直接在a计算时,你计算f的极限,当x倾向于a

x^y情况下,当xy倾向于0时,通常的限制倾向于1 ,并且特别是当x倾向于0x x^x倾向于1

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

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

如果x为零且y为零,则可能会出现域错误。

它也说(7.12.1 / 2):

在域错误上,该函数返回一个实现定义的值; 如果整数expression式math_errhandling&MATH_ERRNO不为零,则整型expression式errno获取EDOM值; 如果整数expression式math_errhandling&MATH_ERREXCEPT为非零,则会引发“无效的”浮点exception。

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

我不同意以前的一些答案,认为这是一个约定或方便的问题(包括各种定理的一些特殊情况等),0 ^ 0定义为1而不是0。

幂乘实际上并不符合我们的其他math符号,所以我们都学习的定义留下了混淆的余地。 接近它的一个稍微不同的方法是说a ^ b(或者exp(a,b),如果你喜欢的话)返回等于乘以某个其他东西的值,重复b次。

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

当你乘以14,乘以0,乘以14,我们乘以1.因此,0 ^ 0 = 1。

这一思路也可能有助于澄清负数和小数指数。 4 ^( – 2)是16号,因为“负乘法”是除法 – 我们除以4。

a ^(1/2)是根(a),因为用a的根乘以一半的乘法工作就是把它乘以一个自身 – 你必须做两次乘以4 = 4 ^ 1 = (4 ^(1/2))^ 2

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

在这里输入图像说明

使用泰勒级数展开零点附近的x^x ,我们得到:

在这里输入图像说明

因此,要知道当x变为零时有什么限制,我们需要找出第二项x log(x)发生了什么,因为其他项与x log(x)成比例地boost到某个能力。

我们需要使用转换:

在这里输入图像说明

现在经过这个转变,我们可以使用L'Hôpital的规定 ,规定:

在这里输入图像说明

所以区分我们得到的转变:

在这里输入图像说明

所以我们计算了当log(x)*x接近0时, log(x)*x接近于零。很容易看出其他连续项也接近于零,甚至比第二项更快。

所以在x=0点,系列变成1 + 0 + 0 + 0 + ...因此等于1。

Interesting Posts