将浮点文字映射到其二进制表示的过程
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
我不确定您为什么需要关心超出指定精度的小数位。
考虑 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
我不确定您为什么需要关心超出指定精度的小数位。