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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19955968/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 17:20:51  来源:igfitidea点击:

Why is Math.pow(0, 0) === 1?

javascriptc++language-agnosticpow

提问by Ionic? Biz?u

We all know that 00is indeterminate.

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

But, javascriptsays that:

但是javascript说:

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

and C++says the same thing:

C++说同样的话:

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

WHY?

为什么?

I know that:

我知道:

>Math.pow(0.001, 0.001)
0.9931160484209338

But why does Math.pow(0, 0)throw no errors? Or maybe a NaNwould be better than 1.

但是为什么不Math.pow(0, 0)抛出错误呢?或者也许 aNaN会比1.

采纳答案by Shafik Yaghmour

In C++ The result of pow(0, 0)the result is basically implementation defined behavior since mathematically we have a contradictory situation where N^0should always be 1but 0^Nshould always be 0for N > 0, so you should have no expectations mathematically as to the result of this either. This Wolfram Alphaforum posts goes into a bit more details.

在 C++中 pow(0, 0)的结果基本上是实现定义的行为,因为在数学上我们有一个矛盾的情况N^0应该总是10^N应该总是0for N > 0,所以你也不应该对这个结果有数学上的期望。这个Wolfram Alpha论坛帖子有更多细节。

Although having pow(0,0)result in 1is useful for many applications as the Rationale for International Standard—Programming Languages—Cstates in the section covering IEC 60559 floating-point arithmeticsupport:

尽管pow(0,0)在涵盖IEC 60559 浮点算术支持的部分中,1作为国际标准的基本原理—编程语言—C状态,结果对于许多应用程序很有用:

Generally, C99 eschews a NaN result where a numerical value is useful. [...] The results of pow(∞,0) and pow(0,0) are both 1, because there are applications that can exploit this definition. For example, if x(p) and y(p) are any analytic functions that become zero at p = a, then pow(x,y), which equals exp(y*log(x)), approaches 1 as p approaches a.

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

Update C++

更新 C++

As leemes correctly pointed out I originally linked to the reference for the complexversion of powwhile the non-complexversion claims it is domain errorthe draft C++ standardfalls back to the draft C standardand both C99and C11in section 7.12.7.4The pow functionsparagraph 2says (emphasis mine):

正如leemes正确地指出我最初链接为基准复杂的版本POW不复杂的版本权利要求它是域误差草案C ++标准回落到草案C标准和两个C99C11中部分7.12.7.4的POW功能2说(强调我的):

[...]A domain error may occurif x is zero and y is zero.[...]

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

which as far as I can tell means this behavior is unspecified behaviorWinding back a bit section 7.12.1Treatment of error conditionssays:

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

[...]a domain error occurs if an input argument is outside the domain over which the mathematical function is defined.[...] On a domain error, the function returns an implementation-defined value; if the integer expression math_errhandling & MATH_ERRNO is nonzero, the integer expression errno acquires the value EDOM; [...]

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

So if there was a domain errorthen this would be implementation defined behaviorbut in both the latest versions of gccand clangthe value of errnois 0so it is not a domain errorfor those compilers.

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

Update Javascript

更新 JavaScript

For Javascriptthe ECMAScript? Language Specificationin section 15.8The Math Objectunder 15.8.2.13pow (x, y)says amongst other conditions that:

对于JavascriptECMAScript?pow (x, y)15.8的数学对象部分中语言规范说,除其他条件外:15.8.2.13

If y is +0, the result is 1, even if x is NaN.

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

回答by zzzzBov

In JavaScript Math.powis defined as follows:

在 JavaScriptMath.pow中定义如下

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

emphasis mine

强调我的

as a general rule, native functions to any language should work as described in the language specification. Sometimes this includes explicitly "undefined behavior" where it's up to the implementer to determine what the result should be, however this is not a case of undefined behavior.

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

回答by schmijos

It is just convention to define it as 1, 0or to leave it undefined. The definition pow(0,0)is wide spread because of the following definition:

它是将其定义为只是约定10或者离开它undefined战俘(0,0)由于以下定义,该定义被广泛传播:

mathematical power definition

数学幂定义



ECMA-Script documentation says the following about pow(x,y):

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

  • 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.
  • 如果 y 为 +0,则结果为 1,即使 x 为 NaN。
  • 如果 y 为 ?0,则结果为 1,即使 x 为 NaN。

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

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

回答by NPE

According to Wikipedia:

根据维基百科:

In most settings not involving continuity in the exponent, interpreting 00as 1 simplifies formulas and eliminates the need for special cases in theorems.

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

There are several possible ways to treat 0**0with pros and cons to each (see Wikipediafor an extended discussion).

有几种可能的方法来处理0**0每种方法的利弊(请参阅维基百科的扩展讨论)。

The IEEE 754-2008floating point standard recommends three different functions:

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

  • powtreats 0**0as 1. This is the oldest defined version. If the power is an exact integer the result is the same as for pown, otherwise the result is as for powr(except for some exceptional cases).
  • powntreats 0**0 as 1. The power must be an exact integer. The value is defined for negative bases; e.g., pown(?3,5)is ?243.
  • powrtreats 0**0 as NaN (Not-a-Number – undefined). The value is also NaN for cases like powr(?3,2)where the base is less than zero. The value is defined by exp(power'×log(base)).
  • pow对待0**01。这是最早定义的版本。如果幂是一个精确整数,则结果与 for 相同pown,否则结果与 forpowr相同(某些特殊情况除外)。
  • pown将 0**0 视为 1。幂必须是一个精确的整数。该值是为负基数定义的;例如,pown(?3,5)?243
  • powr将 0**0 视为 NaN(非数字 - 未定义)。对于powr(?3,2)基数小于零的情况,该值也是 NaN 。该值由 exp(power'×log(base)) 定义。

回答by Thomas Ahle

Donald Knuth

唐纳德·克努斯

sort of settled this debate in 1992 with the following:

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

enter image description here

在此处输入图片说明

And went even more into details in his paper Two Notes on Notation.

并在他的论文《关于符号的两个注释》中更详细地介绍了细节。

Basically, while we don't have 1 as the limit of f(x)/g(x)for all not all functions f(x)and g(x), it still makes combinatorics so much simpler to define 0^0=1, and then just make special cases in the few places where you need to consider functions such as 0^x, which are weird anyway. After all x^0comes up a lot more often.

基本上,虽然我们没有将 1 作为f(x)/g(x)所有函数f(x)和的极限g(x),但它仍然使组合数学的定义变得如此简单0^0=1,然后只需在需要考虑函数的少数地方进行特殊情况,例如0^x,反正很奇怪。毕竟x^0出现的频率要高得多。

Some of the best discussions I know of this topic (other than the Knuth paper) are:

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

回答by Denys Séguret

When you want to know what value you should give to f(a)when fisn't directly computable in a, you compute the limit of fwhen xtends towards a.

当您想知道f(a)f中不能直接计算时应该赋予什么值时a,您可以计算f何时x趋向于的极限a

In case of x^y, usual limits tend towards 1when xand ytend to 0, and especially x^xtends towards 1when xtends to 0.

在 的情况下x^y,通常的限制趋向于1何时xy趋向于0,尤其x^x趋于趋向于1何时x趋向于0

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

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

回答by Pete Becker

The C language definition says (7.12.7.4/2):

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

A domain error may occur if x is zero and y is zero.

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

It also says (7.12.1/2):

它还说(7.12.1/2):

On a domain error, the function returns an implementation-defined value; if the integer expression math_errhandling & MATH_ERRNO is nonzero, the integer expression errno acquires the value EDOM; if the integer expression math_errhandling & MATH_ERREXCEPT is nonzero, the ‘‘invalid'' floating-point exception is raised.

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

By default, the value of math_errhandlingis MATH_ERRNO, so check errnofor the value EDOM.

默认情况下,价值math_errhandling就是MATH_ERRNO,所以检查errno的价值EDOM

回答by NiloCK

I'd like to disagree with some of the previous answers' assertion that it's a matter of convention or convenience (covering some special cases for various theorems, etc) that 0^0 be defined as 1 instead of 0.

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

Exponentiation doesn't actually fit that well with our other mathematical notations, so the definition we all learn leaves room for confusion. A slightly different way of approaching it is to say that a^b (or exp(a, b), if you like) returns the value multiplicatively equivalentto multiplying some other thingby a, repeated b times.

取幂实际上并不适合我们的其他数学符号,所以我们都学习的定义留下了混淆的空间。一种稍微不同的方法是说 a^b(或 exp(a, b),如果你喜欢)返回的值乘法等效于将其他事物乘以a,重复 b 次。

When we multiply 5 by 4, 2 times, we get 80. We've multiplied 5 by 16. So 4^2 = 16.

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

When you multiply 14 by 0, 0 times, we are left with 14. We've multiplied it 1. Hence, 0^0 = 1.

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

This line of thinking might also help to clarify negative and fractional exponents. 4^(-2) is a 16th, because 'negative multiplication' is division - we divide by four twice.

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

a^(1/2) is root(a), because multiplying something by the root of a is half the multiplicative workas multiplying it by a itself - you would have to do it twice to multiply something by 4 = 4^1 = (4^(1/2))^2

a^(1/2) 是 root(a),因为乘以 a 的根是乘法工作的一半,因为乘以 a 本身 - 你必须做两次才能乘以 4 = 4^1 = (4^(1/2))^2

回答by Agnius Vasiliauskas

For this to understand you need to solve calculus:

为了理解这一点,你需要解决微积分:

enter image description here

在此处输入图片说明

Expanding x^xaround zero using Taylor series, we get:

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

enter image description here

在此处输入图片说明

So to understand what's going on with limit when xgoes to zero, we need to find out what's going on with second term x log(x), because other terms are proportional to x log(x)raised to some power.

因此,要了解 limitx变为零时的情况,我们需要找出第二项的情况x log(x),因为其他项x log(x)与某个次幂成正比。

We need to use transformation:

我们需要使用转换:

enter image description here

在此处输入图片说明

Now after this transformation we can use L'H?pital's rule, which states that:

现在经过这个转换,我们可以使用L'H?pital 规则,它指出:

enter image description here

在此处输入图片说明

So differentiating that transformation we get:

区分这种转换,我们得到:

enter image description here

在此处输入图片说明

So we've calculated that term log(x)*xapproaches 0 when x approaches 0. It's easy to see that other consecutive terms also approaches zero and even faster than second term.

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

So at point x=0, series becomes 1 + 0 + 0 + 0 + ...and thus equals to 1.

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