C浮点是否是非确定性的?

Luc*_*ane 13 c numerical

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

  1. C标准规定64位浮点数(双精度)只需要产生大约64位的精度.

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

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

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

有没有现在常见的硬件和软件组合,这真的发生了吗?我在其他线程中看到.net有这个问题,但是通过gcc C可以加倍吗?(例如,我正在测试基于精确相等的连续近似的收敛)

R..*_*R.. 12

具有过度精度的实现的行为(这似乎是您关注的问题)在大多数情况下(尽管不是所有情况)都严格按照标准指定.结合IEEE 754(假设你的C实现遵循附件F),这并没有留下你似乎要问的那种非确定性的空间.特别是,x == x因为有一些规则可以保留表达式中的多余精度以及何时被丢弃,因此禁止(Mehrdad在评论中提到)失败的内容.显式转换和对象的赋值是降低多余精度并确保使用标称类型的操作.

但请注意,仍然存在许多不符合标准的破坏编译器.GCC故意无视它们,除非您使用-std=c99-std=c11(即"gnu99"和"gnu11"选项在这方面有意破坏).在GCC 4.5之前,甚至不支持正确处理过度精度.


sta*_*lue 3

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

基本上,数字是用 80 位还是 64 位表示取决于编译器的想法,并且可能在代码中的任何点发生变化。例如,结果是刚刚测试为非零的数字现在为零。米)

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