为什么某些浮点运算反过来,他们做的方式? (例如123456789f 1 = 123456792

2019-10-29 22:35发布

我想更好地了解浮点运算,实际发生的累计,以及到底为什么结果变成他们的方式主治错误。 下面是具体的3个例子,我目前的工作:

1.)0.1 + 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 -1.0 = -1.1102230246251565E-16又名加入0.1 10次给我一个数略小于1.0。 但是,0.1表示(作为双)作为略大于0.1。 也* 0.1 * 3 *比0.3稍大,但* 0.1 * 8 *略小于0.8

2.)123456789f + 1 = 123456792和123456789f 4 = 123456800。

这是怎么回事这些结果? 这一切都还是有点神秘的给我。

Answer 1:

典型的现代处理器和编程语言使用IEEE-754算法(或多或少)用32位二进制浮点为float和64位二进制浮点为double 。 在double ,使用53位有效。 这意味着,当一个十进制数转换为double ,它被转换为一些数量s•˚F•2 e,其中s是符号(+1或-1)中,f是可在53来表示无符号整数位,并且e为-1074和971(含)之间的整数。 (或者,如果要转换的数量太大,其结果可能是正无穷大或负无穷大。)(那些谁知道浮点格式可能会抱怨指数为妥善-1023和1023之间,但我已经改变了尾数使其成为一个整数。我所描述的数学值,而不是编码。)

转换.1 double收益36028797018963968分之3602879701896397,因为,在所需要的所有形式的数字,一个是最接近0.1。 分母是2 -55,所以e是-55。

当我们添加两个的这些,我们得到7205759403792794 / 36028797018963968.这很好,分子仍小于2 53,所以它符合格式。

当我们添加第三个36028797018963968分之3602879701896397,数学计算结果为10808639105689191 / 36028797018963968.不幸的是,分子过大; 它是大于2 53(9007199254740992)。 因此,浮点硬件不能返回该号码。 它,使之适合某种方式。

如果我们把分子和两个分母,我们有5404319552844595.5 / 18014398509481984.此具有相同的价值,但分子不是整数。 使其适合,硬件便将为整数。 当分数正好是1/2,规则是四周以结果均匀,因此在硬件返回18014398509481984分之5404319552844596。

接下来,我们就当前的总和,18014398509481984分之5404319552844596,并再次添加36028797018963968分之3602879701896397。 这一次,总和7205759403792794.5 / 18014398509481984.在这种情况下,硬件几轮下来,返回18014398509481984分之7205759403792794。

然后,我们添加18014398509481984分之7205759403792794和36028797018963968分之3602879701896397,并且总和9007199254740992.5 / 18014398509481984.注意,分子不仅拥有一小部分,但大于2 53。 因此,我们必须再次减少它,它产生4503599627370496.25 / 9007199254740992四舍五入分子为整数产生9007199254740992分之4503599627370496。

这正是1/2。 在这一点上,舍入误差却不约而同地取消; 添加0.1五次正确地产生0.5。

当我们添加9007199254740992分之4503599627370496和36028797018963968分之3602879701896397,结果是完全5404319552844595.25 / 9007199254740992硬件几轮下来,并返回9007199254740992分之5404319552844595。

现在,你可以看到,我们要反复向下取整。 要添加36028797018963968分之3602879701896397给累计总和,硬件有4分频的分子,使之匹配。 这意味着分数部分始终将是1.25,并且它将被舍去。 因此,在未来四年总和也舍去。 我们结束了9007199254740992分之9007199254740991,这仅仅是小于1。

随着float的代替double ,分子必须适应在24位,所以它必须是小于2 24(16777216)。 因此,123456789是任何运算完成之前就太大了。 它必须被表示为15432099•2 3,这是123456792.加1的确切数学结果是15432099.125•2 3,和舍入有效数为一个整数产量15432099•2 3,所以没有变化。 但是,如果你添加四个,结果15432099.5•2 3,和舍入到15432100•2 3。



文章来源: Why do certain floating point calculations turn the way they do? (e.g. 123456789f +1 = 123456792)