十进制到浮点-舍入逻辑

时间:2018-09-09 07:29:20

标签: floating-point rounding precision

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

1 000 000 032转换为浮点数是0 10011100 11011100110101100101000,实际存储在浮点数中的值是1.0E9,我知道为什么会这样。但是当我使用FloatConverter转换1 000 000 033时。实际存储在浮点数中的值为1 000 000 064。为什么会这样呢?由于1 000 000 032的23个最高有效数字与1 000 000 033

的相同

2 个答案:

答案 0 :(得分:2)

单精度浮点数包含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 064)更接近下一个可表示的值(1 000 000 000),因此当然会四舍五入。但是1000000032恰好在这些值之间,因此取决于实现选择IEEE-754标准指定的允许舍入模式之一:

  

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

     

舍入到最接近的

     
      
  • 四舍五入至最接近的值,四舍五入至最接近的值;如果该数字落在中间,则用偶数(零)最低有效位四舍五入到最接近的值; 这是二进制浮点的默认值,建议使用十进制的默认值
  •   
  • 四舍五入到最接近的值,从零开始舍入-四舍五入到最接近的值;如果该数字落在中间,则四舍五入为大于(对于正数)或小于(对于负数)的最接近值;用作十进制浮点数的选项。
  •   
     

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

似乎在这里使用了推荐的平整关系规则。同样,由于与偶数的联系规则

,将1000000096舍入为1000000128。

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

您还可以尝试使用Exploring Binary's converter,它提供了更多有用的表示形式,并清楚说明了其舍入值的方式

  

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

答案 1 :(得分:1)

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

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

这就是说1.0e9最有可能是显示的,而不是存储的内容。