将浮点数常量映射为其二进制表示的过程

3
考虑围绕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的类型设置为float,值为0.300000011920928955078125。(以上第3种选项)
我很好奇编译器是如何得出这个值,而不是其周围的值。有一种理论是它们调用strtof函数来获取浮点数。这里是strtof的实现(它基本上遍历字符串中的每个字符,乘以10的幂并确定小数点的位置)。 我不明白为什么这种方法会给出第3个选项,而不是第4或第5个选项。

1
你可能会发现将浮点数1864.78转换为二进制和IEEE格式有助于理解如何进行转换。 - David C. Rankin
请查看页面末尾的“正确舍入十进制到浮点数转换”主题。 - phuclv
这些值可能相差1 ULP(最后一位单位)。因此,选项3显然是二进制IEEE-754单精度中24位(而不是23位)精度中可用的最佳值。您是否要求算法?这需要很多工作;不要期望答案适合此论坛。 - Rick James
2个回答

4
一种理论是他们调用strtof函数来获取浮点数。
实际上,它们使用类似于strtof的函数。有开源编译器。您可以查看它们如何解析文字。这里是来自GCC的一个实现Here。它太大了,无法在此处复制。它使用GNU MPFR(多精度浮点)库。
IEEE-754文档在“5.12浮点数据和外部字符序列之间转换的详细信息”一节中指定了此转换在符合IEEE-754标准的系统上必须如何行为。除了转换函数,它还适用于翻译时间转换,例如浮点字面量。

1
C++标准要求使用IEEE-754吗? - Maxim Egorushkin
1
@MaximEgorushkin 不。 - eerorika

-1

你为什么关心这个?

IEEE规定浮点数具有23位有效数字,约为7位小数。因此,“0.3”的二进制表示形式为0.3000000 +/- 精度损失(因为0.3本身无法用二进制表示),其中精度损失小于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

我不确定为什么你需要关心指定精度以外的小数位。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接