为什么NaN ^ 0 == 1

时间:2013-07-25 16:24:19

标签: r math arithmetic-expressions

由一个早期代码打高尔夫提示为什么会:

>NaN^0
[1] 1

NA^0设为1非常有意义,因为NA缺少数据,而任何数字提升为0都会产生1,包括-InfInf。但是NaN应该代表 not-a-number ,为什么会这样呢?当?NaN的帮助页面指出时,这更令人困惑/担忧:

  在R中,基本上所有数学函数(包括基本函数)   算术),应该与+/- Inf和NaN一起正常工作   输入或输出。

     

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

     

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

这背后是否存在哲学原因,还是仅仅与R代表这些常数有关?

6 个答案:

答案 0 :(得分:27)

这在?'NaN'

引用的帮助页面中引用

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

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

在那里你找到了关于应该创建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会感染任何涉及它的计算。除非计算产生相同的结果,无论实际值是否取代NaN,结果都是NaN。”

因此,在编写代码时,GNU-C人员似乎有不同的标准。据报道,2008版ANSI / IEEE 754浮点标准提出了这一建议:

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

已发布的标准不是免费的。因此,如果您有访问权限或金钱,可以在这里查看:

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

答案 1 :(得分:20)

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

似乎IEEE 754引入了两个different power functions - powpowr,后者在OP案例中保留NaN并返回NaN } Inf^00^01^Inf,但最终后者被删除为explained briefly here

从概念上讲,我正处于NaN保留阵营,因为我是从限制的角度来看这个问题,但从便利的角度来看,我希望目前的约定稍微容易处理,即使在某些情况下它们没有多大意义(例如sqrt(-1)^0等于1,而所有操作都是实数,如果有的话就没有意义。)

答案 2 :(得分:15)

是的,我已经迟到了,但作为参与此设计的R Core成员,让我回想一下上面评论过的内容。 NaN保留和NA保留在R中“等效地”起作用,因此如果您同意NA ^ 0应该给出1,NaN ^ 0 | - > 1是结果。

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

  

1 ^ y和y ^ 0是1,总是

而且我很确定我参与其中(如果不是作者)。 请注意,能够提供非NaN答案是非常好的,也不错,在其他编程语言不同的情况下也是如此。 这样一条规则的结果是更多东西能够自动正常工作; 在另一种情况下,R程序员会被要求自己做更多特殊的外壳。

或者换句话说,如上所述的简单规则(在所有情况下都返回非NaN)是一个很好的规则,因为它在数学意义上传播连续性:lim_x f(x)= f(lim x)。 我们有一些案例显然有利于(即不需要特殊的套管,我重复......)遵守上述“= 1”规则,而不是传播NaN。正如我所说的那样,sqrt(-1)^ 0也是这样一个例子,因为只要你扩展到复平面,1 就是正确的结果。

答案 3 :(得分:5)

这是一个推理。来自Goldberg

  

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

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

另请注意:

> 1^NaN
[1] 1

一个是指数为零的数字。

答案 4 :(得分:4)

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

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

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

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

如果一个浮点认识到上述情况,它可以有效地将NaN提升为字面零,因为产生一个,并将其提升到任何其他类型的零,因为产生NaN;这样的规则将允许在许多情况下假设一个恒定的结果,其中可能是NaN的东西将被提升到编译器可以识别为常数零的东西,而没有这样的假设改变程序语义。否则,我认为问题在于,如果x^0NaN,大多数代码都不会关心x NaN是否x^0,并且没有太多意义编译器为条件代码添加代码是不会关心的。请注意,问题不仅仅是计算x^0的代码,还包括基于{{1}}时为常量的计算。

答案 5 :(得分:-1)

如果你看一下NaN的类型,它仍然是一个数字,它不是一个可以用数字类型表示的特定数字。

编辑:

例如,如果你要拿0/0。结果是什么?如果你试图在纸上解决这个等式,你会陷入第一个数字,有多少零适合另一个0?你可以把0,你可以放1,你可以放8,它们都适合0 * x = 0但是不可能知道哪一个是正确的答案。但是,这并不意味着答案不再是一个数字,而是一个可以表示的数字。

无论如何,任何数字,即使是一个你无法代表的数字,仍然是1的幂。如果你分解了一些数学x^8 * x^0可以通过x^(8+0)进一步简化,等同于到x^8x^0去了哪里?这有意义x^0 = 1,因为等式x^8 * 1解释了为什么x^0只是从存在中消失。