十进制到舍入逻辑



我知道有很多关于浮点数的问题,但我仍然找不到我要找的东西。

0 10011100 110111001101011001010001 000 000 032转换为浮点数,并且浮点数中实际存储的值是1.0E9,我理解为什么会发生这种情况。但是当我使用浮子转换器转换1 000 000 033时。浮点数中实际存储的值为1 000 000 064。为什么会这样?由于1 000 000 032的 23 个最高有效数字与1 000 000 033相同

单精度浮点数包含 23 个有效位,而不是有效位和十进制数字。

要了解值是如何舍入的,在二进制编写它们时会更容易看到:

₁₂₃₄₅₆₇₈₉₀¹²³⁴⁵⁶⁷⁸⁹⁰₁₂₃₄₅₆₇₈₉₀
1000000000 = 111011100110101100101000000000 (0x4e6e6b28)
1000000032 = 111011100110101100101000100000
1000000033 = 111011100110101100101000100001
1000000064 = 111011100110101100101001000000 (0x4e6e6b29)
Truncated                            ^^^^^^
Normalized: 1.11011100110101100101000 x 2²⁹

当指数为 29 时,这些值的收盘表示为 1000000000 和 1000000064,它们分别以单精度存储为0x4e6e6b280x4e6e6b29。如您所见,它们在最后一个位置仅相差一位

因此,当我们将 1000000032 和 1000000033 转换为 24 位有效数时,首先截断最后 6 位,然后应用适当的舍入。在1000000033的情况下,很容易看出它比前一个值(1 000 000 000(更接近下一个可表示值(1 000 000 064(,所以它当然会被四舍五入。但是,1000000032恰好介于这些值之间,因此选择IEEE-754标准指定的允许舍入模式之一取决于实现:

该标准定义了五条舍入规则。前两个规则舍入到最接近的值;其他称为有向四舍五入:

四舍五入到最接近

  • 舍入到最近值,与偶数连接 – 舍入到最接近的值; 如果数字落在中间,则四舍五入到最接近的值,并带有偶数(零(最低有效位;这是二进制浮点的默认值,也是十进制的建议默认值
  • 舍入到最近值,从零开始并列 – 舍入到最接近的值;如果数字落在中间,则四舍五入到最接近的值(对于正数(或低于(对于负数(;这旨在作为十进制浮点的一个选项。

https://en.wikipedia.org/wiki/IEEE_754#Rounding_rules

看起来这里使用了推荐的偶数规则关系。同样,由于与偶数规则的联系,1000000096将四舍五入为1000000128

您可以查看Error due to conversion字段,看到1000000032、1000000033 和 1000000096 的误差分别为 -32、31 和 32

您还可以尝试探索二进制的转换器,它提供了更有用的表示形式,并清楚地说明了它如何舍入值

这是一个十进制到二进制浮点转换器。它将十进制数转换为其最接近的单精度和双精度 IEEE 754 二进制浮点数,使用舍入到偶数舍入(默认的 IEEE 舍入模式(。它是使用任意精度算术实现的,因此其转换正确舍入。它将转换正常和次正规数,并将转换溢出(无穷大(或下溢(到零(的数字。

不要假定显示的内容是用十进制表示该显示时存储的内容。 在显示十进制值时,您正在从二进制转换回十进制,并引入舍入和您选择的任何显示方式的表示规则 - 无论是某些库函数还是调试器。

例如,默认情况下,fprintf %f 格式说明符将仅考虑 6 个有效的十进制数字。

也就是说,1.0e9 很可能是显示的内容,而不是存储的内容。

最新更新