65

由早期代码打高尔夫球的地方提示,为什么会:

>NaN^0
[1] 1

为 1 非常有意义,NA^0因为NA缺少数据,任何增加到 0 的数字都会给出 1,包括-InfInf。然而NaN应该代表not-a-number,那为什么会这样呢?当状态的帮助页面时,这更加令人困惑/令人担忧?NaN

在 R 中,基本上所有数学函数(包括 basic Arithmetic)都应该可以正常工作+/- InfNaN作为输入或输出。

基本规则应该是调用和与Infs 的关系确实是具有适当数学限制的语句。

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

这背后是否有哲学原因,或者只是与 R 如何表示这些常数有关?

4

6 回答 6

28

这在参考的帮助页面中被引用?'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

于 2013-07-25T17:49:29.903 回答
20

答案可以用“历史原因”来概括。

似乎 IEEE 754 引入了两种不同的幂函数-pow并且powr,后者NaN在 OP 情况下保留 's 并返回NaN, Inf^0, 0^01^Inf但最终后者被删除,如这里简要解释的那样。

从概念上讲,我在NaN保留阵营,因为我是从限制的角度来解决这个问题的,但从方便的角度来看,我希望当前的约定更容易处理,即使它们不会产生很多在某些情况下有意义(例如sqrt(-1)^0,当所有操作都在实数上时等于 1,如果有的话,意义不大)。

于 2013-07-25T17:49:01.697 回答
17

是的,我来晚了,但作为参与此设计的 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就是正确的结果。

于 2013-11-23T17:34:10.550 回答
5

这是一个原因。从戈德堡

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

NaN浮点数也是如此,尽管具有特殊含义。将数字提高到零次幂会将其指数设为零,因此它将不再是 NaN。

另请注意:

> 1^NaN
[1] 1

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

于 2013-07-25T17:19:30.393 回答
4

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

顺便说一句,我会认识到的四种情况是:

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

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

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

于 2013-07-25T18:45:11.140 回答
-1

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

编辑:

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

无论如何,任何数字,即使是你无法表示的数字,0 次方仍然是 1。如果你分解一些数学x^8 * x^0可以进一步简化为x^(8+0)等于x^8,那么哪里x^0去了?这是有道理的,x^0 = 1因为这样方程就x^8 * 1解释了为什么x^0只是从存在中消失了。

于 2013-07-25T16:36:59.747 回答