众所周知,IEEE float 可以存储所有整数和 2 的倒数幂的整数倍(例如 1/2 或 3/4)的精确表示,只要这些数字保持在浮点类型。
但是,浮点解析器通常能保证解析此类数字的十进制表示的准确结果吗?
例如,如果我在 C 程序中使用 0.75
作为 double
文字,编译器是否会保证编译后的代码包含 3/4 的精确表示,或者是否存在产生 0.7 的不精确表示和 0.05 的不精确表示之和的风险?
或者,同样,如果我使用 3e4
作为 double
文字,精确的 3 可能会乘以 2^(4*ln(10) 的某些不精确表示形式/ln(2)) 或一些类似的数学?
在这件事上,FP 解析器通常需要遵循什么标准,还是通常完全留给实现?如果是后者,有谁知道像 GCC 或 glibc 这样的实际重要实现实际上是如何工作的?
我主要只是出于好奇,而不是因为我想依赖这种行为;但有时,如果知道这些值仅来自文字源,那么知道 FP 相等比较保证有效可能会非常方便。
最佳答案
根据 C 2011 6.4.4.2 3,C 标准允许浮点常量是最接近文字常量的精确值的可表示值,或者是紧邻最接近值的较大或较小的可表示值。 C 实现做得更好。现代实现应该做得更好,因为已经发布了可以正确进行转换的算法。
但是,C 标准还提供了十六进制浮点常量,这使得编译器可以轻松正确地进行转换。十六进制浮点常量的基本形式为 0xhhh.hhhpeee,其中 hhh 是十六进制数字eee 是十进制指数,可以有符号。 (“.”一侧的十六进制数字为零时可以省略,省略右边的数字时可以省略句点。)指数是2的幂。
C 标准要求,如果在 C 实现中 float 的基数是 2 的幂,则必须正确舍入十六进制浮点常量。如果无法准确表示十六进制常量,它建议生成诊断消息。
例如,0x3p-2
应该正好是 0.75。
关于parsing - 编译器解析精确 float ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14331719/