这个涉及到浮点数的结构(符号位,指数部分,尾数部分),以及规格化的表示和非规格化的表示。
这里不详细解释,LZ可查阅相关资料
有几个知识点:
1.计算机中浮点数的基数是2.
2.指数部分有偏移量(float为127, double为1023)
3.规格化的表示小数点左边一定为1.(二进制数)
4.float类型 符号位占1位,指数部分占8位,尾数占23位(因为规格化表示,小数点左边一定为1,所以实际有24位精度)
5.double类型 符号位占1位,指数部分占11位,尾数占52位(因为规格化表示,小数点左边一定为1,所以实际有53位精度)
看一个例子float 0.6吧:
第一步,把十进制转2进制:
0.6的二进制表示(乘2取整,顺序表示):
.1001 1001 1001 1001 1001 1001 1001 ... 无限循环下去。
第二步,计算尾数部分:
把.1001 1001 1001 1001 1001 1001 1001 ...规格化表示(小数点移到第一个非0书右边)就是:
1.001 1001 1001 1001 1001 1001 1001 ...,右移了1位。
由于规格化表示的数小数点左边一定为1,把这个1舍弃,并保留float尾数能表示的23位,最终尾数部分是:
001 1001 1001 1001 1001 1001
第三步,计算指数部分:
由于计算尾数时右移了1位,相当于乘以2的负1次,所以指数为-1,加上float偏移量127,最后指数为126,
二进制表示为 0111 1110
第四步,符号部分:
0.6为正数,符号位为0
最终0.6在计算机中的表示就是:
符号位 指数 尾数
0 0111 1110 001 1001 1001 1001 1001 1001
--------------------------------------------------------------
我们再从这个2进制来计算10进制数:(2的指数次 * 尾数)
符号位0--> 为正
指数 0111 1110:为126, 减去偏移量127,结果为-1.
尾数 001 1001 1001 1001 1001 1001: 规格化的时候小数点左边人掉了一个1,现在加上:
1.001 1001 1001 1001 1001 1001,转为10进制就是:
1*2^0 + 1*2^-3 + 1*2^-4 + .....= 1.19999992847442626953125
1.19999992847442626953125 * 2^-1 = 0.599999964237213134765625
所以最终结果是一个无限接近于0.6而不能精确表示0.6
具体更详细的解释和相关知识点,可以自行查阅以及参考收藏中的相关文章介绍