相关概念:
(1)64位双精度存储,计算机存储数据的类型之一,该存储类型的一个存储单元包括符号位,指数域,尾数域。
(2)符号位,对双精度来说位于第64位,占1个比特,代表数据是的正负,位于存储单元的最高为。
(3)指数位,对双精度来说位于第63位到第53位,占11个比特,代表尾数的指数部分的二进制。另外为了便于比较,该区域存储的均为非负值,将指数的实际值(-1023~1024)加上1023,所以得出存储值的范围是0~2047。
(4)尾数位,对双精度来说位于第52位到第1位,将小数转化为二进制后,通过添加指数位使小数位转化位1.****,其中正数1不占据尾数位,作为一个默认值,所以实际尾数位只是*******...*****(共52位)
0.1转化为二进制:
0.1 * 2 = 0.2
0.2 * 2 = 0.4
0.4 * 2 = 0.8
0.8 * 2 = 1.6
0.6 * 2 = 1.2
0.2 * 2 = 0.4
...
所以0.1的二进制小数位 0.00011001100...(1100循环),就是1.10011001100...(1100循环) * 2^-4,所以得出此时的存储单元为0(符号位)01111111011(指数位)1001100110011001100110011001100110011001100110011010(小数位最后一位是0舍1入得来的)。
0.2转化位二进制:
0.2 * 2 = 0.4
0.4 * 2 = 0.8
0.8 * 2 = 1.6
0.6 * 2 = 1.2
0.2 * 2 = 0.4
....
所以0.2的二进制小数位0.00110011...(1100循环),就是1.10011001100...(1100循环) * 2^-3,所以得出此时的存储单元为0(符号位)01111111100(指数位)1001100110011001100110011001100110011001100110011010(小数位最后一位是0舍1入得来的)。
此时两个数的存储已经可视化了,接下来是运算+,首先需要将指数位转化位一样,规则是小转大,所以小数位也会跟着变化。
0.1 -> 0.11001100...(1100循环) * 2^-3(第一个1是之前隐藏的整数位),开始运算。
0.1 + 0.2 =
0.11001100110011001100110011001100110011001100110011010(最后一位0超出舍弃)
+
1.1001100110011001100110011001100110011001100110011010
= 10.0110011001100110011001100110011001100110011001100111
将整数位10格式化位尾数位。
小数点左移一位:1.00110011001100110011001100110011001100110011001100111
去掉溢出的最后一位:1.0011001100110011001100110011001100110011001100110100(最后一位1,0舍1入得到此值)
左移后指数域+1:01111111101
最终结果:0(符号位)01110010111(指数位)0011001100110011001100110011001100110011001100110100(尾数位) = 0.30000000000000004
另一种方法,把小数换成二进制直接运算
0.1 -> 0.000110011001100110011001100110011001100110011001100110011
第一个1后只能有52位所以0舍1入后
0.1 -> 0.00011001100110011001100110011001100110011001100110011010
+
0.2 -> 0.0011001100110011001100110011001100110011001100110011001
= 0.010011001100110011001100110011001100110011001100110100(0舍1入)
注:0舍1入都是为了使数据在小数位上只有52位。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。