- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
为什么NaN值的比较行为与所有其他值不同?
也就是说,与一个或两个值均为NaN的运算符==,<=,> =,<,>进行的所有比较均返回false,这与所有其他值的行为相反。
我想这以某种方式简化了数值计算,但是我找不到明确陈述的理由,甚至在Kahan的Lecture Notes on the Status of IEEE 754中也没有详细讨论其他设计决策。
在进行简单的数据处理时,这种异常行为会引起麻烦。例如,在对记录列表进行排序时我需要在C程序中的某些实值字段中编写额外的代码,以将NaN作为最大元素来处理,否则排序算法可能会变得混乱。
编辑:
到目前为止,所有答案都表明,比较NaN毫无意义。
我同意,但这并不意味着正确答案是错误的,
而是一个非布尔值(NaB),幸运的是不存在。
因此,在我看来,返回true或false进行比较的选择是任意的,
对于常规数据处理,如果遵循通常的法律将是有利的
(自反性==,三分法为<,==,>),
以免依赖这些定律的数据结构变得混乱。
因此,我要求打破这些法律的某些具体优势,而不仅仅是哲学推理。
编辑2:
我想我现在明白为什么将NaN设置为最大值是一个坏主意,它将使上限计算变得混乱。
NaN!= NaN可能需要避免检测诸如
while (x != oldX) {
oldX = x;
x = better_approximation(x);
}
最佳答案
我是IEEE-754委员会的成员,我将尽力帮助澄清一些事情。
首先,浮点数不是实数,并且浮点算术不满足实数算术的公理。三分法不是实数运算的唯一属性,它对浮点数不成立,甚至不是最重要的。例如:
加法不是关联的。
分配法不成立。
有没有反数的浮点数。
我可以继续。不可能指定一个固定大小的算术类型来满足我们所知道和喜欢的真实算术的所有属性。 754委员会必须决定弯曲或折断其中的一些。这遵循一些非常简单的原则:
如果可以,我们匹配实数运算的行为。
当我们无法做到时,我们会尝试使违规行为可预测且易于诊断。
关于您的评论“并不意味着正确答案是错误的”,这是错误的。谓词(y < x)
询问y
是否小于x
。如果y
为NaN,则它不小于任何浮点值x
,因此答案必然为假。
我提到三分法不适用于浮点值。但是,确实存在类似的属性。 754-2008标准的第5.11条第2款:
可能存在四个互斥关系:小于,相等,大于和无序。当至少一个操作数为NaN时,将出现最后一种情况。每个NaN都应将无序与所有事物(包括自身)进行比较。
就编写额外的代码来处理NaN而言,通常有可能(尽管并不总是那么容易)以适当的方式构造代码,以使NaN完全失效,但这并非总是如此。如果不是,则可能需要一些额外的代码,但这对于以代数闭包为浮点算术带来的便利来说是一个很小的代价。
附录:
许多评论者认为,采用NaN!= NaN似乎并没有保留任何熟悉的公理,因此保持平等和三分法的反身性会更有用。我承认对此观点有些同情,所以我想我将重新审视这个答案并提供更多背景信息。
通过与Kahan交谈,我的理解是NaN!= NaN源自两个务实的考虑:
该x == y
应尽可能与x - y == 0
等效(除了作为实数算法的定理之外,这还使得比较的硬件实现更加节省空间,这在标准制定时就显得尤为重要。 (x = y = infinity)被违反,因此它本身并不是一个很大的理由;它可以合理地弯腰为(x - y == 0) or (x and y are both NaN)
。
更重要的是,在8087算法中将NaN形式化时没有isnan( )
谓词;有必要为程序员提供一种方便有效的方法来检测NaN值,而这些值不依赖于编程语言,而提供isnan( )
这样的代码可能要花费很多年。我将引用卡汉(Kahan)在该主题上的文章:
如果没有摆脱NaN的方法,它们将像CRAY上的Infinites一样无用;一旦遇到一个问题,最好是停止计算,而不是无限期地继续计算以得出不确定的结论。这就是为什么对NaN进行的某些操作必须提供非NaN结果的原因。哪些操作? …例外是C个谓词“ x == x”和“ x!= x”,对于每个无穷或有限数x分别为1和0,但如果x不是数字(NaN),则相反。这些提供了NaN和数字之间唯一简单的,无例外的区分,即缺少NaN单词和谓词IsNaN(x)的语言中的数字。
注意,这也是排除返回“ Not-A-Boolean”之类的逻辑的逻辑。也许这种实用主义放错了地方,该标准应该要求isnan( )
,但这将使NaN在全世界等待编程语言采用的几年中几乎无法高效,方便地使用。我不认为这是一个合理的权衡。
直言不讳:NaN == NaN的结果现在不会改变。学会与之相处比在网络上抱怨更好。如果您想主张还应该存在适合于容器的顺序关系,我建议提倡您喜欢的编程语言实现IEEE-754(2008)中标准化的totalOrder
谓词。事实并非如此,这说明了卡汉(Kahan)的担忧之效,这激发了当前的局势。
关于floating-point - 对于IEEE754 NaN值,所有比较返回false的理由是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47413126/
除非 IEEE 754 是 NaN、+-0.0 或 +-Infinity,否则自除是否保证结果正好是 1.0? 同样,减去本身是否保证总是导致 +-0.0? 最佳答案 IEEE 754-2008 4.
我已经阅读了一些文本和线程,展示了如何从十进制转换为 IEEE 754,但我仍然对如何在不扩展小数(以科学计数法表示)的情况下转换数字感到困惑 我特别使用的数字是9.07 * 10^23,但任何数字都
为什么 float 中的指数要置换 127? 那么,真正的问题是:与 2 的补码相比,这种表示法有什么优势? 最佳答案 由于存储的指数是无符号的,因此可以使用整数指令来比较浮点值。为了比较(不是补码)
我一直在使用 Mendeley 的 Microsoft Word 插件轻松引用我的 Mendeley 桌面图书馆中的论文。 但是,我注意到 IEEE 格式的引用书目/引文在引用 session 记录和
我花了一周的时间研究这个主题,发现没有语言能够正确满足 IEEE 754 规范。 甚至 GCC 也不尊重相关的 C99 部分(它忽略了 FENV_ACCESS 编译指示,并且我被告知我的工作示例纯粹是
有很多 IEEE 标准。几乎所有语言都保证实现 IEEE 754 二进制 float 。 最佳答案 我认为这只是流水号,就像 IRC 有 RFC1459 关于ieee-754 - IEEE 754 f
我们在类里面有一个作业,要使用 c 从十进制转换为单精度,但我完全迷失了。 这是作业: The last part of this lab involves coding a short c algo
我使用的是在 SoftFloat 库中实现的半 float (阅读:100% IEEE 754 兼容),为了完整起见,我希望为我的代码提供与 float.h> 用于 float、double 和 lo
我很难理解IEEE 754舍入约定: 四舍五入为正无穷大 四舍五入为负无穷大 无偏到最接近的偶数 如果我在二进制点的右边有一个由9位组成的二进制数,并且我需要使用最右边的3位来确定舍入该怎么办? 这是
关闭。这个问题需要更多focused .它目前不接受答案。 想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post . 4年前关闭。 Improve this questi
我创建了以下程序来查找 float 的位模式。但我的计算结果有所不同: #include int main(void){ float f = 1.234; char *ch;
我在 18 位软核处理器目标上有一个 gcc 交叉编译器定义了以下数据类型:18 位整数、36 位长整型和 36 位 float (单精度)。现在我的重点是浮点运算。由于宽度是非标准(36位),我有以
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 8 年前。 Improve th
Analog Devices 的 BFF-533 处理器不提供原生浮点支持,但提供浮点仿真。 使用 IDE VisualDSP++,用户可以在高性能浮点和严格的 IEEE 合规性之间进行选择。 据我了
我在没有浮点单元的处理器上工作,所以我必须为用户界面使用固定或自定义浮点类型。 对于这三种类型,say a multiply 的性能如何: IEEE float (32) 具有 16 位有符号值和有符
我对浮点数的工作原理有很好的理解,但我想知 Prop 体的指数和尾数大小是如何决定的。它们在某些方面是最优的吗?如何测量浮点表示的最优性(我假设有几种方法)?我想这些问题在官方标准中得到了解决,但我无
任何人都建议使用良好的压缩算法,该算法可与 double 浮点值一起很好地工作?我们发现,对于浮点值的二进制表示,使用常见的压缩程序(例如Zip,RAR,7-Zip等)会导致非常差的压缩率。 我们需要
我正在尝试将 0.0000211 转换为二进制。目前我的理解是这样的: E = -偏差 + 1。偏差 = 15,E = -14 符号位和指数 = 0。 所以我有: 0 00000 ?????????
我试图找出 ieee 754 中存在多少个不同的整数。我得到的数字是 1778384895,但我找不到任何资源来检查自己。预先非常感谢。 最佳答案 我将假设单精度 float 。 我们得到了零,虽然可
在运行 32 位 GCC 7.3.0 的特定在线判断中,这个: #include volatile float three = 3.0f, seven = 7.0f; int main() {
我是一名优秀的程序员,十分优秀!