C浮点数不确定吗? [英] Is C floating-point non-deterministic?

查看:53
本文介绍了C浮点数不确定吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have read somewhere that there is a source of non-determinism in C double-precision floating point as follows:

  1. C标准规定,仅产生约64位精度就需要64位浮点数(双精度数).

  1. The C standard says that 64-bit floats (doubles) are required to produce only about 64-bit accuracy.

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

Hardware may do floating point in 80-bit registers.

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

Because of (1), the C compiler is not required to clear the low-order bits of floating-point registers before stuffing a double into the high-order bits.

这意味着YMMV,即结果可能会出现微小差异.

This means YMMV, i.e. small differences in results can happen.

现在真的会发生什么常见的硬件和软件组合吗?我在其他线程中看到.net存在此问题,但是C是否通过gcc可以加倍执行?(例如,我正在测试基于精确相等性的逐次逼近的收敛性)

Is there any now-common combination of hardware and software where this really happens? I see in other threads that .net has this problem, but is C doubles via gcc OK? (e.g. I am testing for convergence of successive approximations based on exact equality)

推荐答案

在大多数情况下(即使不是全部情况下),标准都严格规定了实现精度过高的行为,这似乎是您关注的问题.与IEEE 754结合使用(假设您的C实现遵循附件F),这不会为您似乎要询问的不确定性留出空间.特别是,诸如 x == x (Mehrdad在评论中提到)之类的故障是被禁止的,因为对于何时在表达式中保留超精度以及何时将其丢弃有一些规则.显式强制转换和对对象的分配属于会降低精度的操作,并确保您使用的是名义类型.

The behavior on implementations with excess precision, which seems to be the issue you're concerned about, is specified strictly by the standard in most if not all cases. Combined with IEEE 754 (assuming your C implementation follows Annex F) this does not leave room for the kinds of non-determinism you seem to be asking about. In particular, things like x == x (which Mehrdad mentioned in a comment) failing are forbidden since there are rules for when excess precision is kept in an expression and when it is discarded. Explicit casts and assignment to an object are among the operations that drop excess precision and ensure that you're working with the nominal type.

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

Note however that there are still a lot of broken compilers out there that don't conform to the standards. GCC intentionally disregards them unless you use -std=c99 or -std=c11 (i.e. the "gnu99" and "gnu11" options are intentionally broken in this regard). And prior to GCC 4.5, correct handling of excess precision was not even supported.

这篇关于C浮点数不确定吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆