Ion*_*zău 84 javascript c++ language-agnostic pow
我们都知道0 0是不确定的.
但是,javascript说:
Math.pow(0, 0) === 1 // true
Run Code Online (Sandbox Code Playgroud)
和C++说同样的话:
pow(0, 0) == 1 // true
Run Code Online (Sandbox Code Playgroud)
为什么?
我知道:
>Math.pow(0.001, 0.001)
0.9931160484209338
Run Code Online (Sandbox Code Playgroud)
但为什么不Math.pow(0, 0)
抛出错误呢?或者也许NaN
会比...更好1
.
Sha*_*our 78
在C++中,pow(0,0)的结果基本上是实现定义的行为,因为在数学上我们有一个矛盾的情况N^0
应该始终是1
但0^N
应该总是0
为了N > 0
,所以你不应该在数学上对这个结果没有任何期望.这个Wolfram Alpha论坛帖子详细介绍了一些.
虽然pow(0,0)
结果1
对于许多应用程序很有用,因为国际标准编程语言的基本原理-C在涉及IEC 60559浮点运算支持的部分中指出:
通常,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而不复杂的版本声称它是域误差的草案C++标准回落到草案C标准和两个C99和C11中部分7.12.7.4
的POW功能段2说(强调我的):
[...] 如果x为零且y为零,则可能发生域错误.[...]
据我所知,这意味着这种行为是未指明的行为绕回一个部分7.12.1
错误条件的处理说:
[...]如果输入参数位于定义数学函数的域之外,则会发生域错误.[...]在域错误中,函数返回实现定义的值; 如果整数表达式math_errhandling&MATH_ERRNO非零,则整数表达式errno获取值EDOM; [...]
因此,如果存在域错误,那么这将是实现定义的行为,但是在最新版本gcc
和clang
值中errno
都是0
如此,因此对于那些编译器而言不是域错误.
更新Javascript
对于Javascript,ECMAScript®语言规范在pow(x,y)下15.8
的数学对象部分中说明以下条件:15.8.2.13
如果y为+0,则结果为1,即使x为NaN.
zzz*_*Bov 35
- 如果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.
强调我的
作为一般规则,任何语言的本机函数都应按照语言规范中的描述进行操作.有时,这包括明确的"未定义行为",由实现者决定结果应该是什么,但这不是未定义行为的情况.
sch*_*jos 16
这仅仅是约定将其定义为1
,0
或离开它undefined
.定义 因为以下定义而广泛传播:
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 ]
NPE*_*NPE 14
根据维基百科:
在大多数不涉及指数连续性的设置中,将0 0解释为1简化了公式,并且消除了定理中特殊情况的需要.
有几种可能的方法来对待0**0
每种方法的利弊(参见维基百科的扩展讨论).
在IEEE 754-2008浮点标准推荐三种不同的功能:
pow
对待0**0
为1
.这是最早定义的版本.如果功率是精确整数,则结果与结果相同pown
,否则结果为powr
(除了一些例外情况).pown
将0**0视为1.功率必须是精确整数.该值定义为负基数; 例如,pown(?3,5)
是?243
.powr
将0**0视为NaN(非数字 - 未定义).对于powr(?3,2)
基数小于零的情况,该值也是NaN .该值由exp(power'×log(base))定义.在1992年的这场辩论中解决了以下问题:
基本上,虽然我们没有1为限f(x)/g(x)
对所有不是所有的函数f(x)
和g(x)
,它仍然使组合学这么多简单的定义0^0=1
,然后才使特殊情况在一些地方,你需要考虑的功能,例如0^x
,它无论如何都很奇怪.毕竟x^0
更频繁地出现了.
我所知道的关于这个主题的一些最好的讨论(除了Knuth论文)是:
当你想知道什么时候你应该给出什么值f(a)
,f
而不能直接计算a
,你可以计算出趋于f
何时的极限.x
a
在的情况下x^y
,通常的限制趋向1
时x
和y
趋向于0
,尤其是x^x
朝着趋于1
时x
趋于0
.
见http://www.math.hmc.edu/funfacts/ffiles/10005.3-5.shtml
C语言定义说(7.12.7.4/2):
如果x为零且y为零,则可能发生域错误.
它还说(7.12.1/2):
在域错误上,该函数返回一个实现定义的值; 如果整数表达式math_errhandling&MATH_ERRNO非零,则整数表达式errno获取值EDOM; 如果整数表达式math_errhandling&MATH_ERREXCEPT非零,则引发''invalid''浮点异常.
默认情况下,价值math_errhandling
的MATH_ERRNO
,所以检查errno
的价值EDOM
.