math - 用初学者的话来说,NaN(非数字)是什么?
问题描述
我仍然不明白 NaN 或(不是实数的数字)到底是什么。
主要问题:
- NaN 值或 NaN 究竟是什么(用非数学教授的话来说)?
此外,我对整个情况有几个问题,这让我抱怨理解 NaN 应该是什么,这不是回答我的主要问题所必需的,而是想要的:
什么是导致 NaN 值的操作?
为什么 0.0 / 0.0 的结果声明为未定义?不应该是0吗?
为什么任何数学运算的结果都不能用浮点数或整数来表示?一个值怎么可能是不可表示的?
为什么负数的平方根不是实数?
为什么 NaN 不等于不定?
我没有在整个互联网上找到任何可以理解的解释 NaN 对我来说是什么,包括在 Stack Overflow 上。
无论如何,我想提供我的研究作为地方的链接,我已经扫描了我的问题以找到一个可以理解的答案,即使一些链接在其他编程语言中指向同一个问题,但总体上没有给我想要的清晰信息:
维基百科:
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
堆栈溢出:
其他语言的类似或相同问题(我提供它们,只要我认为理解的基础非常相似,如果不相同):
对于 IEEE754 NaN 值返回 false 的所有比较的基本原理是什么?
JavaScript中的(内置)方法来检查字符串是否为有效数字
C++ 的问题:
为什么使用英特尔 C++ 编译器时 NaN - NaN == 0.0?
感谢您提供所有有用的答案和评论。
解决方案
你在这里问了一系列很好的问题。这是我试图解决每个问题的尝试。
NaN 值或 NaN 究竟是什么(用非数学教授的话来说)?
假设您正在处理实数 - 1、π、e、-137、6.626 等数字。在实数领域,通常可以执行一些操作,但有时没有定义结果。例如,让我们看一下对数。您可以取许多实数的对数:例如,ln e = 1,而 ln 10 约为 2.3。但是,从数学上讲,负数的对数没有定义。也就是说,我们不能取 ln (-4) 并返回一个实数。
所以现在,让我们跳到编程领域。想象一下,你正在编写一个程序来计算一个数字的对数,并且用户以某种方式希望你除以一个负数的对数。应该发生什么?
这个问题有很多合理的答案。您可以让操作引发异常,这在 Python 等某些语言中完成。
然而,在硬件层面(由设计 IEEE-754 标准的人)做出的决定是给程序员第二个选择。与其让程序崩溃,不如让操作产生一个值,表示“你想让我做一些不可能的事情,所以我报告一个错误”。完成此操作的方法是让操作产生特殊值NaN
(“非数字”),这表明在您的计算中的某个地方,您尝试执行数学上未定义的操作。
这种方法有一些优点。在许多科学计算设置中,代码执行一系列长计算,定期生成可能感兴趣的中间结果。通过未定义的操作产生NaN
因此,程序员可以编写代码,按照他们的意愿进行数学运算,然后在代码中引入特定点,他们将测试操作是否成功。从那里,他们可以决定做什么。与触发异常或彻底崩溃程序相比,这意味着程序员要么需要保护每一系列可能失败的浮点操作,要么必须自己手动测试。这是关于哪个选项更好的判断调用,这就是您可以启用或禁用浮点 NaN 行为的原因。
什么是导致 NaN 值的操作?
有很多方法可以NaN
从操作中获得结果。这是一个采样器,虽然这不是一个详尽的列表:
- 取负数的对数。
- 取负数的平方根。
- 从无穷大中减去无穷大。
- 对 执行任何算术运算
NaN
。
NaN
然而,有些操作即使在数学上是未定义的,也不会产生。例如,将正数除以零会得到正无穷大,即使这不是数学定义的。这样做的原因是,如果当 y 从正方向接近零时,将 x / y 设为正 x 的极限,则值会无限增长。
为什么 0.0 / 0.0 的结果声明为未定义?不应该是0吗?
这更像是一个数学问题。这与限制的工作方式有关。让我们考虑如何定义 0 / 0。一种选择是这样说:如果我们看表达式 0 / x 并在 x 接近零时取极限,那么我们会在每个点看到 0,所以极限应该为零。另一方面,如果我们查看表达式 x / x 并在 x 接近 0 时取极限,我们会在每个点看到 1,因此极限应该是 1。这是有问题的,因为我们希望 0 / 0 的值与您在评估这些表达式中的任何一个时发现的值一致,但我们无法选择一个有意义的固定值。结果, 0 / 0 的值被评估为NaN
,表明这里没有明确的值可分配。
为什么任何数学运算的结果都不能用浮点数或整数来表示?一个值怎么可能是不可表示的?
这与 IEEE-754 浮点数的内部结构有关。直观地说,这归结为一个简单的事实:
- 有无限多个实数,其中有无限多个具有无限长的非重复小数,但是
- 您的计算机内存有限。
因此,存储任意实数可能需要存储无限长的数字序列,而我们的有限内存计算机无法做到这一点。因此,我们有浮点数存储不是非常大的实数的近似值,而无法表示值的原因是我们只是存储了近似值。
有关如何实际存储数字以及这在实践中意味着什么的更多信息,请查看传奇指南“每个程序员应该了解的浮点运算知识”
为什么负数的平方根不是实数?
我们以 √(-1) 为例。想象这是一个实数 x;也就是说,假设 x = √(-1)。平方根的概念是,它是一个数字,如果与自身相乘,则返回取平方根的数字。
那么... x 是多少?我们知道 x ≠ 0,因为 0 2 = 0 不是 -1。我们也知道 x 不可能是正数,因为任何正数乘以自身都是正数。而且我们也知道 x 不可能是负数,因为任何负数乘以自身都是正数。
我们现在有一个问题。无论这个 x 是什么,它都必须不是正数,不是零,也不是负数。这意味着它不是一个实数。
您可以通过引入一个数字 i 将实数推广到复数,其中 i 2 = -1。请注意,由于上述原因,没有实数会这样做。
为什么 NaN 不等于不定?
“不确定”和“不管它是什么,它都不是一个实数”之间是有区别的。例如,0 / 0 可以说是不确定的,因为根据你接近 0 / 0 的方式,你可能会得到 0、1 或其他东西。另一方面,√(-1) 被完美地定义为一个复数(假设我们有 √(-1) 返回 i 而不是 -i),所以问题不在于“这是不确定的”作为“它有一个值,但该值不是实数。”
希望这可以帮助!
推荐阅读
- clang-format - Clang 格式语法在自己的行上获取初始化程序左大括号
- google-cloud-platform - 如何获取用户帐户的承载访问令牌以访问云存储桶中的受保护数据
- java - 将动态值作为参数传递给@Value 注释
- python - 在涉及@retry的python中为函数编写单元测试用例
- java - 使库来自 maven
- api - 新 Instagram API 的小图像尺寸 graph.instagram.com/me/media
- android - 默认情况下,如何使用手动(键盘)输入显示时间选择器对话框?
- reactjs - 无法在 expo 项目中安装 npm 包
- html - 单击表单输入元素时转到其他页面
- graphql - 我应该如何在 Gatsby 中存储数据(100 x 2 数组)?