令double d = 9.2,为什么int a = d * 10是92而不是91?

问题描述

d = 9.2的二进制表示应类似于9.199999999999999289457264239899814128875732421875。

所以10d应该是91.999999999xxxxxxx。

让int a = 10d,不是将其截断为91​​而不是92吗?

解决方法

执行乘法运算时,将实数结果四舍五入为IEEE-754 binary64格式,四舍五入后的结果为92。

将9.2转换为二进制64中可以表示的最接近值时,结果的确是9.199999999999999289457264239899814128875732421875。使用十六进制表示有效位数,这是1.2666666666666 16 •2 3

当我们使用实数运算将其乘以10时,结果为 B.7FFFFFFFFFFFC 16 •2 3 。 (这很容易看到。从右边开始,6乘以10是60 10 ,这是3C 16 。因此,我们写出C数并携带3。在下一列中,将6乘以10再乘以3C 16 ,然后将带进位的3加到3F 16 。我们写F位数并携带3。继续产生更多的F位数并将3的进位传播到最前面,其中2乘以10加3的进位就是23 10 = 17 16 ,因此我们写出7并进位1 。最后1加10的1是11 10 = B 16 。)

让我们调整该数字以使其规范化,以使基数点仅剩一点点。将有效位数右移三位并通过在指数上加三进行补偿,得到1.6FFFFFFFFFFFF8 16 •2 6 。现在我们可以看到此数字的位数太多,无法适合binary64格式。开头的1有1位,接下来的13位有4位,而最后的8位有1个有效位(1000 2 ,后跟的零只是占位符,不是有效位)。也就是54位,但是binary64格式的有效位数只有53个(52个显式存储在有效位数字段中,一个通过指数字段编码)。因此,我们必须对其进行舍入以使其符合格式。

两个最接近的可表示值是1.6FFFFFFFFFFFF 16 •2 6 和1.7000000000000 16 •2 6 。它们与1.6FFFFFFFFFFFFFF8 16 •2 6 的距离相等,并且打破平局的规则是选择具有偶数低位的数字。因此结果是1.7000000000000 16 •2 6

因此,在Binary64算术中将9.199999999999999289457457264239899899814128875732421875乘以10得到1.7 16 •2 6 ,即92。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...