为什么 NaN 不等于 NaN? [复制]

2023-11-26

相关的 IEEE 标准定义了一个数字常量 NaN(不是数字),并规定 NaN 应该与自身进行比较。这是为什么?

我熟悉的所有语言都实现了这个规则。但它经常会导致严重的问题,例如,当 NaN 存储在容器中时、当 NaN 位于正在排序的数据中时,等等。更不用说,绝大多数程序员都希望任何对象都等于其自身(在他们了解 NaN 之前),因此让他们感到惊讶会增加错误和混乱。

IEEE 标准是经过深思熟虑的,所以我确信 NaN 与其自身进行比较是不好的,这是有充分理由的。我就是不明白那是什么。

编辑:请参考对于 IEEE754 NaN 值,所有比较都返回 false 的理由是什么?作为权威答案。


接受的答案是 100% 毫无疑问是错误的。不是半途而废,甚至是轻微的错误。我担心当这个问题出现在搜索中时,这个问题会在很长一段时间内让程序员感到困惑和误导。

NaN 被设计为在所有计算中传播,像病毒一样感染它们,因此,如果在深入、复杂的计算中遇到 NaN,您不会冒出看似合理的答案。否则,根据恒等式 NaN/NaN 应该等于 1,以及所有其他结果,如 (NaN/NaN)==1、(NaN*1)==NaN 等。如果您想象您的计算在某个地方出错了(舍入产生了零分母,产生 NaN)等,那么你可能会从你的计算中得到非常不正确(或更糟糕:微妙不正确)的结果,而没有明显的指示来说明原因。

当探究数学函数的值时,在计算中使用 NaN 也是有充分理由的;链接文档中给出的示例之一是查找函数 f() 的 zeros()。完全有可能在用猜测值探测函数的过程中,您将探测函数 f() 不会产生合理结果的函数。这允许 Zeros() 看到 NaN 并继续其工作。

NaN 的替代方法是一旦遇到非法操作(也称为信号或陷阱)就触发异常。除了您可能会遇到的巨大性能损失之外,当时无法保证 CPU 会在硬件中支持它,或者操作系统/语言会在软件中支持它;每个人在处理浮点运算时都有自己独特的雪花。IEEE 决定在软件中将其明确处理为 NaN 值,以便它可以跨任何操作系统或编程语言移植。正确的浮点算法在所有浮点实现中通常都是正确的,无论是 node.js 还是 COBOL(哈哈)。

理论上,您不必设置特定的 #pragma 指令、设置疯狂的编译器标志、捕获正确的异常或安装特殊的信号处理程序来使看似相同的算法实际上正常工作。不幸的是,一些语言设计者和编译器编写者一直忙于尽其所能地取消​​此功能。

请阅读有关 IEEE 754 浮点历史的一些信息。此外,委员会成员还对类似问题做出了回答:对于 IEEE754 NaN 值,所有比较都返回 false 的理由是什么?

《浮点老人访谈录》

《IEEE 浮点格式的历史》

每个计算机科学家都应该了解的浮点运算知识

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 NaN 不等于 NaN? [复制] 的相关文章

  • 生成所有多集大小为 n 的分区的算法

    我一直在试图找出一种方法来生成多重集的所有不同的大小为 n 的分区 但到目前为止却空手而归 首先让我展示一下我想要实现的目标 假设我们有一个输入向量uint32 t std vector
  • 什么时候应该使用双精度而不是十进制?

    我可以说出使用的三个优点double or float 代替decimal 使用更少的内存 速度更快 因为处理器本身支持浮点数学运算 可以表示更大范围的数字 但这些优点似乎只适用于计算密集型操作 例如建模软件中的操作 当然 当需要精度时 例
  • 验证假名输入

    我正在开发一个允许用户输入日语字符的应用程序 我试图想出一种方法来确定用户的输入是否是日语假名 平假名 片假名或汉字 应用程序中的某些字段不适合输入拉丁文文本 我需要一种方法将某些字段限制为仅限汉字或仅限片假名等 该项目使用UTF 8编码
  • 负整数的基数排序

    我正在尝试对整数 包括负整数 实现基数排序 对于非负整数 我计划为数字0 9创建一个10个队列的队列 并实现LSD算法 但我对负整数有点困惑 我现在的想法是继续为它们创建另一个包含 10 个队列的队列 并分别对它们进行排序 然后在最后 我将
  • Python 中的舍入浮点问题

    我遇到了 np round np around 的问题 它没有正确舍入 我无法包含代码 因为当我手动设置值 而不是使用我的数据 时 返回有效 但这是输出 In 177 a Out 177 0 0099999998 In 178 np rou
  • 使用随机放置的 NaN 创建示例 numpy 数组

    出于测试目的 我想创建一个M by Nnumpy 数组与c随机放置的 NaN import numpy as np M 10 N 5 c 15 A np random randn M N A mask np nan 我在创建时遇到问题mas
  • 什么是拉姆达?

    有人可以很好地描述什么是 Lambda 吗 我们为它们设置了一个标签 它们涉及 C 问题的秘密 但我还没有找到一个很好的定义和解释来解释它们是什么 闭包 lambda 和匿名函数不一定是同一件事 匿名函数是任何没有 或者至少不需要 自己名称
  • C语言中如何比较float变量和double变量?

    float num1 1 if num1 1 printf Yes it is equal n else printf No it is not equal n 输出 gt 是的 它是相等的 whereas float num1 1 2 i
  • 如何高效计算连续数的数字积?

    我正在尝试计算数字序列中每个数字的数字乘积 例如 21 22 23 98 99 将会 2 4 6 72 81 为了降低复杂性 我只会考虑 连续的数字 http simple wikipedia org wiki Consecutive in
  • 如果找不到指定的图像文件,显示默认图像的最佳方式?

    我有一个普通的电子商务应用程序 我将 ITEM IMAGE NAME 存储在数据库中 有时经理会拼错图像名称 为了避免 丢失图像 IE 中的红色 X 每次显示产品列表时 我都会检查服务器中是否有与该产品相关的图像 如果该文件不存在 我会将其
  • 在没有 epsilon 的情况下可以将浮点数与 0.0 进行比较吗?

    我知道 要比较两个浮点值 需要使用一些 epsilon 精度 因为它们并不精确 但是 我想知道是否存在边缘情况 我不需要那个 epsilon 特别是 我想知道这样做是否总是安全的 double foo double x if x lt 0
  • 标准数学函数在不同 CPU 上的再现性

    我正在做一个需要大量数学计算的项目 打开新的测试机后 我注意到很多测试都失败了 但同样重要的是要注意 测试在我的开发机器以及其他开发人员的某些机器上也失败了 经过跟踪值并与旧机器的值进行比较后 我发现一些功能 此时我只发现cosine ma
  • 从关系数据库中“区分”对象

    我们的 win32 应用程序根据 MySQL 关系数据库中多个表中的数据组装对象 对于这样的对象 多个修订版本存储在数据库中 当存储某些内容的多个修订版本时 迟早您会问自己这样的问题 您是否可以想象两个修订版本之间的差异 所以我的问题是 比
  • 用矩阵变换 3D 向量的方法

    我一直在阅读一些关于用矩阵转换 Vector3 的文章 并且正在努力深入研究数学并自己编码 而不是使用现有代码 无论出于何种原因 我的学校课程从未包含矩阵 所以我正在填补我的知识空白 值得庆幸的是 我认为我只需要一些简单的东西 背景是我正在
  • 查找两个大小为 n 的数组中第 n 大数的算法

    我有这个问题 给定两个大小为 n 的排序列表 存储在数组中 找到 O log n 计算并集中第 n 大元素的算法 两个列表 我可以看到这里可能有一个技巧 因为它需要第 n 个最大的元素 并且数组的大小也是 n 但我不知道它是什么 我在想我可
  • MySQL如何进行浮点加法的数学计算?

    我测试过SELECT 0 1 0 2 用MySQL MariaDB 查询 它返回了正确的答案 MariaDB none gt SELECT 0 1 0 2 0 1 0 2 0 3 1 row in set 0 000 sec 在大多数编程语
  • 有人还在使用客户端服务器架构吗[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我编写软件已有几十年了 现在一切都是网络 在网络出现之前 我们拥有的客户端服务器应用程序基本上是直接与数据库对话的胖客户端应用程序 它
  • 删除 Pandas 数据框中的 NaN/NULL 列?

    我有一个dataFrame在 pandas 中 有些列的值全部为空 是否有内置函数可以让我删除这些列 Yes dropna See http pandas pydata org pandas docs stable missing data
  • iOS5 Xcode4.2浮点字节对齐错误?

    看这段代码 这是具有 1 字节结构包装的结构定义文件 用于套接字网络 pragma pack 1 typedef struct TestStruct1 double d1 double d2 TestStruct1 typedef stru
  • 承诺的反面是什么?

    承诺代表将来可能可用 或无法实现 的值 我正在寻找的是一种数据类型 它表示将来可能变得不可用的可用值 可能是由于错误 Promise a b TransitionFromTo

随机推荐