一、进制的转化
1、十进制转二进制:
整数
9 = 1*2^3 + 0*2^2 + 0*2^1 + 1*2^0
=1001
或者除以二取余数部分,将得到的余数按先后顺序从右往左连起来:
9 / 2 ...... 1 2^0
4 / 2 ...... 0 2^1
0 / 2 ...... 0 2^2
1 / 2 ...... 1 2^3
小数
0.9 = 1*2^-1 + 1*2^-2 + 1*2^-3 + 0*2^-4 + ...
=0.1110...
或者乘以二取整数部分,将得到的余数按先后顺序从左往右连起来:
2*0.9 1.8 ** 取1
2*0.8 1.6 ** 取1
2*0.6 1.2 ** 取1
2*0.2 0.4 ** 取0
...
2、二进制转十进制:
整数
1001 = 1*2^3 + 0*2^2 + 0*2^1 + 1*2^0 = 9
小数
0.1110 = 1*2^-1 + 1*2^-2 + 1*2^-3 + 0*2^-4 = 0.875 ≈ 0.9
二、计算机如何存储0.1+0.2?
js中,数值均以64位浮点数保存,即用64个二进制位保存数值,具体如何保存呢?
1.先将数值转化为二进制
2.按照下图公式进行格式化

3.从格式化的公式里提取出s,M,E

4.连成浮点数
第0~第51位用来保存有效数字M的小数部分, 如1.1010中的1010;
第52~第62位,这11位长度用来保存指数部分,E
其中,因为这11个二进制位本身无法表示负数,当指数为-5的情况就无法表示。所以用0~1023来表示非正数部分,
1024~2047表示正数部分。
第63位,保存s
按图二顺序将64位连在一起,即得到结果
以0.1的浮点数表示来说明以上过程:
先将0.1 转化成 二进制
2*0.1 0.2 ** 取0
2*0.2 0.4 ** 取0
2*0.4 0.8 ** 取0
2*0.8 1.6 ** 取1
2*0.6 1.2 ** 取1
2*0.2 0.4 ** 取0
2*0.8 0.8 ** 取0
2*0.8 1.6 ** 取1
2*0.6 1.2 ** 取1
2*0.2 0.4 ** 取0
2*0.8 0.8 ** 取0
2*0.8 1.6 ** 取1
...
即:
0.000 1100 1100 1100...
以科学计数法表示:
(-1)^s * 1.100 1100 1100... * 2^E
s = 0
M = 1.100 1100 1100...,因其小数部分共分配了52个位置,所以其小数部分为:
100 1100{12} 1,
E,可以看出以科学计数法的有效数字的小数点右移了4位,所以E = -4,用分配给指数部分的11个二进制位来表示出-4。
但前面说过,这11个二进制位的实际表示范围是:
0~1023来表示非正数部分-1023~0,1024~2047表示正数部分1~1024。所以-4实际用的-4+1023 = 1019表示,化成11位二进制即:01111111011
所以0.1最终表示为:
0 0111 1111 011 100 1100{12} 1。
上面说的多是废话,最关键的一点是想告诉一个结论:
M为52位
所以,10进制数 0.1,在计算机中存储的二进制数实际上是:
0.1 = 0.0001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1010
(最后的1010是由0.0001 1001{12} 1001 1... “四舍五入”的结果
同理计算0.2可以得到下面的表达式
0.1:0.00011001100110011001100110011001100110011001100110011010
0.2:0.0011001100110011001100110011001100110011001100110011001
0.1+0.2:0.01001100110011001100110011001100110011001100110011001110

0.01001100110011001100110011001100110011001100110011001110 转化为十进制:
=2^-2 + 3*2^-6* ((2^4 - 2^44) / 2^4-1) + 2^-53 + 2^-54 + 2^-55
=0.3 - 2^-50*0.2 + 2^-53 + 2^-54 + 2^-55
=0.3 + 0.6*2^-55
算出来和网上的答案有出入:
0.30000000000000004
疑问:
找到的资料在讲这个问题是,都是得到0.30000000000000004之后就说所以0.1+0.2 != 0.3,
这让我更加疑惑,为什么他们都不继续说0.3在计算机中的表示值(就是指那个64位浮点数),或者在计算机中的实际存储值(64位浮点数代表的真实10进制数)呢?
难道计算机是直接比较的
0.30000000000000004 != 0.3 ???
我觉得应该是比较的 0.30000000000000004 的64位浮点数和 0.3 的64位浮点数才合理呀,因为要是可以直接比较10进制,那说明他就可以直接存10进制,绕这么大一圈干嘛。但是为什么所有的资料都只说到0.30000000000000004就不提了呢
网友评论