将浮点文字映射到其二进制表示的过程

process of mapping a floating point literal to its binary representation

考虑 0.3 左右的精确浮点值

1) 0.2999999523162841796875
2) 0.2999999821186065673828125
3) 0.300000011920928955078125
4) 0.3000000417232513427734375
5) 0.30000007152557373046875

当我们用C++编写如下代码时

auto x = 0.30f

编译器必须解析 0.30f 标记并使 x 的类型为浮点值 0.300000011920928955078125。 (以上选项 3)

我很好奇编译器是如何达到这个值的,而不是它周围的值。一种理论是他们调用 strtof 函数来获取浮点数。 Here 是 strtof 的实现(它基本上遍历字符串的每个字符,乘以 10 的幂并计算出小数点的位置)。我不明白为什么这个方法会给出选项 3 而不是选项 4 或 5。

One theory is that they call strtof function to get the float.

确实;他们使用的函数相当于 strtof。有开源编译器。你可以看看他们是如何解析文字的。 Here 是 GCC 的一个实现。这里复制太大了。它使用 GNU MPFR (multiple-precision floating-point) 库。

IEEE-754 文档在标题为 5.12 floating-point 数据和外部字符序列之间的转换详细信息.除了转换函数,它还适用于翻译时间转换,例如浮点文字的转换。

你为什么关心这个?

IEEE 指定浮点数为 23 位有效数,即小数点后 7 位。所以“0.3”的二进制表示是 0.3000000 +/- precision_loss(因为 0.3 本身不能用二进制表示),其中 precision_loss 小于 0.0000001.

此外,根据您获得“0.3”的方式,相同十进制数的二进制表示可能会有所不同。例如:

    float n = 0.3;
    cout << std::fixed << std::setprecision(25) << n << endl;
    float n1 = 0.1;
    cout << std::fixed << std::setprecision(25) << n1 + 0.1 + 0.1 << endl;

给出以下输出:

0.3000000119209289550781250
0.3000000014901161304869959

我不确定您为什么需要关心超出指定精度的小数位。