13

我在某处读到 C 双精度浮点中存在不确定性的来源,如下所示:

  1. C 标准说,需要 64 位浮点数(双精度)才能产生大约 64 位精度。

  2. 硬件可以在 80 位寄存器中进行浮点运算。

  3. 由于 (1),C 编译器不需要在将 double 填充到高位之前清除浮点寄存器的低位。

  4. 这意味着 YMMV,即结果可能会发生微小差异。

是否有任何现在常见的硬件和软件组合真正发生这种情况?我在其他线程中看到.net 有这个问题,但是 C 通过 gcc 加倍好吗?(例如,我正在测试基于精确相等的逐次逼近的收敛性)

4

3 回答 3

12

在大多数情况下(如果不是所有情况),标准都严格规定了精度过高的实现行为,这似乎是您关心的问题。结合 IEEE 754(假设您的 C 实现遵循附件 F),这并没有为您似乎在询问的那种不确定性留下空间。特别是,诸如x == x(Mehrdad 在评论中提到的)失败之类的事情是被禁止的,因为有一些规则规定了何时在表达式中保持超精度以及何时丢弃它。显式转换和分配给对象是降低过度精度并确保您使用标称类型的操作之一。

但是请注意,仍然存在许多不符合标准的损坏编译器。GCC 故意忽略它们,除非您使用-std=c99or -std=c11(即“gnu99”和“gnu11”选项在这方面被故意破坏)。在 GCC 4.5 之前,甚至不支持正确处理超精度。

于 2014-06-21T10:34:34.273 回答
3

这可能发生在使用 x87 浮点单元的 Intel x86 代码上(可能除了 3.,这似乎是假的。LSB 位将设置为零。)。所以硬件平台很常见,但在软件方面,x87 的使用正在逐渐消失,取而代之的是 SSE。

基本上,一个数字是用 80 位还是 64 位表示是编译器的心血来潮,并且可能在代码中的任何位置发生变化。例如,结果是刚刚测试非零的数字现在为零。米)

请参阅“验证浮点计算的陷阱”,第 8 页。

于 2014-06-21T09:00:22.410 回答
1

测试浮点中的精确收敛(或相等)通常是一个坏主意,即使在完全确定的环境中也是如此。FP 是一开始的近似表示。在指定的 epsilon 内测试收敛性要安全得多。

于 2014-06-21T15:15:50.590 回答