为什么NaN ^ 0 == 1

以前的代码打高尔夫球的提示为什么会:

>NaN^0 [1] 1 

NA^0为1是因为NA是缺失数据,而任何数字升到0将给1,包括-InfInf 。 不过, NaN应该代表非数字 ,那为什么这样呢? 当?NaN的帮助页面显示时,这更令人困惑/令人担忧:

在R中,基本上所有的math函数(包括基本算术)都可以用+/- Inf和NaN作为input或输出。

基本的规则应该是与Infs的呼叫和关系确实是具有适当的math限制的陈述。

涉及NaN的计算将返回NaN或NA :这两个中的哪一个不能保证,并且可能依赖于R平台(因为编译器可能会重新sorting计算)。

这背后有一个哲学的原因,还是仅仅是如何处理R代表这些常量?

这在?'NaN'引用的帮助页面中被引用,

“IEC 60559标准,也被称为ANSI / IEEE 754浮点标准。

http://en.wikipedia.org/wiki/NaN“; 。

在那里你可以find关于什么应该创build一个NaN的声明:

  "There are three kinds of operations that can return NaN:[5] Operations with a NaN as at least one operand. 

它可能来自特定的C编译器,正如引用的注释所表示的那样。 这就是GNU C文档所说的:

http://www.gnu.org/software/libc/manual/html_node/Infinity-and-NaN.html

另一方面,NaN感染涉及它的任何计算,除非计算结果会产生相同的结果,不pipe哪个实际值取代NaN,结果都是NaN。

所以在编写代码时,GNU-C似乎有不同的标准。 据报道,2008年版的ANSI / IEEE 754浮点标准提出了这样的build议:

http://en.wikipedia.org/wiki/NaN#Function_definition

公布的标准不是免费的。 所以,如果你有访问权限或金钱,你可以看看这里:

http://ieeexplore.ieee.org/xpl/mostRecentIssue.jsp?punumber=4610933

答案可以归结为“历史原因”。

看起来,IEEE 754引入了两个不同的幂函数 – powpowr ,后者保留NaN在OP情况下,还返回NaNInf^0 0^0 1^Inf ,但最终后者被作为在这里简要解释 。

从概念上讲,我是在NaN保护阵营,因为我从限制的angular度来看这个问题,但是从方便的angular度来看,我希望现在的习惯稍微容易处理,即使他们没有很多在某些情况下(例如, sqrt(-1)^0等于1,而所有的操作都是实数的情况下(如果有的话)是没有意义的)。

是的,我迟到了,但作为参与这个devise的R核心成员,让我回想一下我上面所说的。 NaN保持和NA保持在R中“等价地”工作,所以如果你同意NA ^ 0应该给1,那么结果就是NaN ^ 0 | – > 1。

事实上(正如其他人所说的),您应该真正阅读R的帮助页面,而不是C或IEEE标准,来回答这些问题,并正确引用了SimonO101

1 ^ y和y ^ 0总是1

而且我非常确定,我曾经深深卷入(如果不是作者的话)。 请注意,能够提供非NaN答案是好的 ,也是不错的 ,在其他编程语言做不同的情况下也是如此。 这样的规则的后果是更多的事情自动正确工作, 在另一种情况下,R程序员本来会被要求做更多特殊的套件。

或者换句话说,上面的简单规则(在所有情况下返回非NaN)是一个很好的规则,因为它在math意义上传播连续性:lim_x f(x)= f(lim x)。 我们有一些情况显然是有利的(即不需要特别的套pipe,我正在重复..)坚持上面的“= 1”规则,而不是传播NaN。 正如我进一步说的那样,sqrt(-1)^ 0也是一个例子,因为只要你延伸到复平面,1 就是正确的结果。

这是一个推理。 来自Goldberg :

在IEEE 754中,NaN通常表示为具有指数e_max + 1和非零有效数的浮点数。

所以NaN是一个浮点数,虽然有特殊的意义。 将一个数字增加到功率零点将其指数设置为零,因此它将不再是NaN。

另请注意:

 > 1^NaN [1] 1 

一个是已经指数为零的数字。

从概念上来说, NaN^0 == 1唯一的问题是零值至less可以有四种不同的方式,但IEEE格式对它们中的三个使用相同的表示。 上述公式对于最常见的情况(这是三者中的一种)是平等的,对其他情况则不适用。

顺便说一下,我会认识到的四个案例是:

  • 一个文字零
  • 无符号零:无法区分的两个数字之间的差异
  • 正无穷小:两个匹配符号数目的乘积或者商数,这个符号太小而不能与零区分。
  • 负无穷小数:两个相反符号数目的乘积或商数,它太小而不能与零相区分。

其中的一些可能是通过其他方式产生的(例如,文字零可以产生为两个文字零的总和;通过非常小的数字划分非常小的正数无穷小等)。

如果一个浮点承认了上述内容,那么可以将NaN提升到一个零,然后将其提升到任何其他types的零以产生NaN; 这样的规则将允许在许多情况下假定一个恒定的结果,在这种情况下,可能是NaN的东西将被提升到编译器可以识别为常数零的地方,而没有这样的假设改变程序语义。 否则,我认为问题是大多数代码不会关心x^0是否可能是NaN ,如果xNaN ,并且没有太多的NaN ,编译器添加条件代码不会关心的代码。 请注意,问题不仅仅是计算x^0的代码,而且还包括基于x^0时常数的计算。

如果你看NaN的types,它仍然是一个数字,它不是一个可以用数字types表示的具体数字。

编辑:

例如,如果你要取0/0。 结果是什么? 如果你试图在纸面上解决这个方程,你会卡在第一个数字,有多less个零适合于另一个0? 你可以把0,你可以把1,你可以把8,他们都适合0 * x = 0,但是不可能知道哪一个是正确的答案。 但是,这并不意味着答案不再是一个数字,它不是一个可以表示的数字。

不pipe怎么说,任何数字,即使是你不能表示的数字,也不能代表0的幂数。如果分解一些mathx^8 * x^0可以用x^(8+0)进一步简化相当于x^8x^0去了哪里? 这是有道理的,如果x^0 = 1因为那么方程x^8 * 1解释了为什么x^0只是从存在消失。