用初学者的话来说NaN(Not a Number)是什么?

What is NaN (Not a Number) in the words of a beginner?

我仍然不明白 NaN 或(不是实数的数字)究竟是什么。

主要问题:

  1. 什么是 NaN 值或确切的 NaN(用非数学教授的话说)?

此外,我对整个情况有几个问题,这让我抱怨理解 NaN 应该是什么,这不是回答我的主要问题所必需的,但却是我想要的:

  1. 导致 NaN 值的操作是什么?

  2. 为什么 0.0 / 0.0 的结果声明为未定义?不应该是0吗?

  3. 为什么数学运算的结果不能用浮点数或整数表示?一个值怎么可能是不可表示的呢?

  4. 为什么负数的平方根不是实数?

  5. 为什么 NaN 不等于不定?

我没有在整个 Internet 上(包括 Stack Overflow 上)找到任何关于 NaN 对我来说是什么的可以理解的解释。


无论如何,我想提供我的研究作为地点的链接,我已经扫描以找到我的问题的可以理解的答案,即使某些链接指向其他编程语言的相同问题,但没有给我总共需要清晰的信息:

维基百科:

https://en.wikipedia.org/wiki/NaN

https://en.wikipedia.org/wiki/IEEE_754

其他:

http://foldoc.org/Not-a-Number

https://www.youtube.com/watch?v=HN_UmxIVS6M

https://www.youtube.com/watch?v=9EsHjXftO7s

堆栈溢出:

其他语言的相似或相同问题(我提供这些问题是因为我认为理解的基础非常相似,即使不相同):

In Java, what does NaN mean?

What is the rationale for all comparisons returning false for IEEE754 NaN values?

(Built-in) way in JavaScript to check if a string is a valid number

JavaScript: what is NaN, Object or primitive?

C++ 问题:

What is difference between quiet NaN and signaling NaN?

Checking if a double (or float) is NaN in C++

Why does NaN - NaN == 0.0 with the Intel C++ Compiler?

What is the difference between IND and NAN numbers


感谢您提供所有有用的答案和评论。

浮点数被编码为位模式,但并未使用所有可用的位模式(对于给定的位数),因此有些位模式不对任何浮点数进行编码。如果找到此类模式,则它们 treated/displayed 为 NaN。

数学数字系统包含 "set" 个值。例如,正整数是 0、1、2、3、4 等。负整数是 -1、-2、-3、-4 等(也可能是 -0,具体取决于您的数学分支)。

在计算机领域,浮点数还有 "infinity" 和 "not a number" 等概念。这就像数字的 "NULL" 。意思是"the floating-point value does not represent a number in the mathematical sense".

当程序员 float 还不想给出数字值时,它们对程序员很有用,浮点标准也使用它们来表示 "invalid" 经营业绩。

例如,您可以通过零除以零来得到 NaN,这是我所知道的任何数学分支中都没有有意义值的运算:如何在 [=24 之间分享一些蛋糕=]没有人?

(如果您尝试使用没有 NaN 或无穷大概念的整数来执行此操作,您将得到一个 [可怕的名字] "floating point exception";换句话说,您的程序将崩溃。)

阅读有关 Wikipedia's article about NaN 的更多信息,它几乎可以回答您的所有问题。

有关摘要,您可以查看 wikiedia page:

In computing, NaN, standing for not a number, is a member of a numeric data type that can be interpreted as a value that is undefined or unrepresentable, especially in floating-point arithmetic. Systematic use of NaNs was introduced by the IEEE 754 floating-point standard in 1985, along with the representation of other non-finite quantities such as infinities.

在实际方面我要指出这一点:

如果 x 或 y 是 NaN 浮点数:则表达式如下:

x<y
x<=y
x>y
x>=y
x==x

总是错误的。然而,

x!=x

将为 true,这是一种检查 x 是否为 NaN 的方法(参见 std::isnan)。

另一个要点是,当数值计算中出现一些 NaN 时,您可能会观察到速度大幅下降(这也可能是调试时的提示)

NaN operations on Intel CPUs are likely to generate exceptions which invoke microcode, so the relative slowdown probably varies greatly with CPU model.

例如见NaN slowdown

您在这里提出了一系列很好的问题。这是我尝试解决每个问题的尝试。

What is a NaN value or NaN exactly (in the words of a non-math professor)?

假设您正在处理实数 - 像 1、π、e、-137、6.626 等数字。在实数领域,有一些运算 通常 可以执行,但有时没有定义的结果。例如,让我们看一下对数。可以取很多实数的对数:例如ln e = 1,ln 10 约为2.3。但是,在数学上,负数的对数没有定义。也就是说,我们不能取 ln(-4) 并取回一个实数。

那么现在,让我们跳到编程领域。想象一下,您正在编写一个程序来计算一个数的对数,而用户希望您以某种方式除以一个负数的对数。应该发生什么?

这个问题有很多合理的答案。您可以让操作抛出异常,这是在某些语言中完成的,例如 Python.

但是,在硬件层面(由设计 IEEE-754 标准的人员)做出的决定是为程序员提供第二个选择。不是让程序崩溃,而是让操作产生一个值,这意味着 "you wanted me to do something impossible, so I'm reporting an error." 这样做的方法是让操作产生特殊值 NaN ("Not a Number"),表示您在计算的某处尝试执行数学上未定义的操作。

这种方法有一些优点。在许多科学计算设置中,代码执行一系列长时间计算,定期生成可能感兴趣的中间结果。通过让未定义的操作产生 NaN 作为结果,程序员可以编写只按照他们希望完成的数学运算的代码,然后在代码中引入特定的位置,他们将在这些位置测试是否操作成功与否。从那里,他们可以决定要做什么。将此与引发异常或程序彻底崩溃进行对比——这意味着程序员要么需要保护每一系列可能失败的浮点运算,要么必须自己手动测试。这是关于哪个选项更好的判断调用,这就是您可以启用或禁用浮点 NaN 行为的原因。

What are operations which causing a NaN value as result?

有很多方法可以从操作中获得 NaN 结果。这是一个采样器,虽然这不是一个详尽的列表:

  1. 取负数的对数。
  2. 对负数求平方根。
  3. 从无穷大中减去无穷大。
  4. 正在对 NaN 执行任何算术运算。

但是,有些操作即使在数学上未定义,也不会产生 NaN。例如,将一个正数除以零得到正无穷大,即使这在数学上没有定义。这样做的原因是,当 y 从正方向趋近于零时,如果您对正 x 取 x / y 的极限,则该值会无限制地增长。

Why is the result of 0.0 / 0.0 declared as undefined? Shouldn´t it be 0?

这更像是一道数学题。这与限制的工作方式有关。让我们考虑如何定义 0 / 0。一种选择是:如果我们查看表达式 0 / x 并在 x 接近零时取极限,那么我们会在每个点看到 0,因此极限应该为零。另一方面,如果我们查看表达式 x / x 并在 x 接近 0 时取极限,我们会在每个点看到 1,因此极限应该是 1。这是有问题的,因为我们希望 0 / 0 的值与您在评估这些表达式中的任何一个时发现的值一致,但我们无法选择一个有意义的固定值。结果,0 / 0 的值被评估为 NaN,表明此处没有要分配的明确值。

Why can´t the result of any mathematical operation be expressed by a floating point or integer number? How can it be that a value is unrepresentable?

这与 IEEE-754 浮点数的内部结构有关。直觉上,这归结为一个简单的事实

  1. 有无穷多个实数,其中无穷多个有无穷长的不重复小数,但是
  2. 您的计算机内存有限。

因此,存储任意实数可能需要存储无限长的数字序列,而我们的有限内存计算机无法做到这一点。因此,我们有浮点数存储 实数 的近似值 并不大得惊人 ,并且无法表示值是因为我们'只是存储近似值。

有关数字实际如何存储的更多信息,以及这在实践中意味着什么,请查看传奇指南 "What Every Programmer Should Know About Floating-Point Arithmetic"

Why is the square root of a negative number not a real number?

以√(-1)为例。假设这是一个实数 x;也就是说,假设 x = √(-1)。平方根的概念是,它是一个数字,如果与它自身相乘,则返回你对其进行平方根的数字。

所以...x 是多少?我们知道 x ≠ 0,因为 02 = 0 不是 -1。我们也知道 x 不可能是正数,因为任何正数乘以它本身都是正数。而且我们知道x不能为负数,因为任何负数乘以它本身都是正数。

我们现在遇到了一个问题。不管这个 x 是什么,它都必须不是正数、零和负数。这意味着它不是一个实数。

您可以通过引入数字 i 将实数概括为复数,其中 i2 = -1。请注意,由于上述原因,没有实数会这样做。

Why is NaN not equivalent to indefinite?

"indefinite" 和 "whatever it is, it's not a real number." 之间有区别 例如,0 / 0 可以说是不确定的,因为根据你接近 0 / 0 的方式,你可能会得到 0 或 1 ,或者其他东西。另一方面,√(-1) 被完美定义为一个复数(假设我们有 √(-1) 返回 i 而不是 -i),所以问题不是 "this is indeterminate"作为 "it's got a value, but that value isn't a real number."

希望对您有所帮助!