浮点数在计算机中的存储
在回答问题之前先研究一下浮点数在计算机中是怎么存储的吧,之后你就会得到答案的。
一、负数用补码表示
负数之所有用补码表示,是出于性能的考虑。因为如果不用补码表示的话,需要多一步判断是否为负数,如果是负数还得把加法变成减法或者减法变成加法,因此耗费性能。使用补码,对于负数的加减操作,实际上和正数加减法操作是一样的。
二、十进制小数与二进制的转换
大家可能都知道十进制整数转为二进制数的方法是除2取余法,但二进制小数是如何转换的呢?乘2取整法。
但是并不是所有的小数都可以用二进制表示,由于计算机的资源是有限的,所有没办法用二进制精确地表示0.1,只能用近似值,就是在有限的精度情况下,最大化接近 0.1 的⼆进制数,于是就会造成精度缺失的情况。
三、计算机存储小数的方式
浮点数在计算机中的存储
在计算机中,小数属于浮点数。
那么浮点数的存储原理其实是采用科学计数法的方式,专业名词叫规格化。
比如 1000.101 这种⼆进制数,规格化表示成 1.000101 x 2^3 ,其中,最为关键的是 000101 和 3 这两个东⻄,它就可以包含了这个⼆进制小数的所有信息:
- 000101 称为尾数,即小数点后面的数字
- 3 称为指数,指定了小数点在数据中的位置
大多数计算机,采用IEEE国际标准存储浮点数
- 符号位:表示正负数,0正数,1负数;
- 指数位:指定了小数点在数据中的位置,指数可以是负数,也可以是正数,指数位的长度越长则数值的表达范围就越大;
- 尾数位:小数点右侧的数字,也就是小数数部分,比如⼆进制 1.0011 x 2^(-2),尾数部分就是 0011, 而且尾数的长度决定了这个数的精度,因此如果要表示精度更高的小数,则就要提高A片尾数位的长度;
float与double在存储上的区别
浮点数在计算机上的存储过程
为什么需要加上127这个偏移量呢?
float 的指数部分是 8 位,IEEE 标准规定单精度浮点的指数取值范围是 -126 ~ +127 ,于是为了把指数转换成无符号整数,就要加个偏移量,⽐如 float 的指数偏移量是 127 ,这样指数就不会出现负数了。
同时小数点左边的有效位1消失了,这是因为规格化,无论如何小数点左侧的数只能是1,所以没必要存储,只需要计算的时候加上就可以了,而且这样做能让尾数位多存储一位,提高精度。
(-1)^符号位x(1+尾数位)x2^(指数-127)
四、0.1+0.2==0.3?
0.1的二进制浮点数转为为十进制的结果是
0.100000001490116119384765625
0.2的二进制浮点数转为十进制的结果是
0.20000000298023223876953125
相加的结果是
0.300000004470348358154296875
所以计算机中的0.1+0.2并不等于0.3
主要是因有的小数计算机无法用完整的二进制表示,只能取近似值。