C++中的float&double的存储原理

参考:https://cloud.tencent.com/developer/article/1473541

  

 

对于任何数字表示成二进制科学计数法以后,一定是1点几(尾数)乘以2的多少次方(指数)。对于小于零的负数来说,就是负1点几(尾数)乘以2的多少次方(指数)。所以要存这个数,需要存储三个部分:正负号,尾数,指数。(尾数:二进制科学计数法中小数点后面的值,指数:2的幂

以float类型的0.6为例:

 这种二进制表示小数的方法,造成了一个隐含的问题:一些本来不是无限循环的十进制小数,表示成二进制之后成了无限循环小数。比如上图中的十进制数字0.6,表示成二进制之后成了循环体为1001的无限循环小数。这就是“浮点数有精度问题”的根源之一,你在代码中声明一个变量double a = 0.6;时,计算机底层其实是无法精确存储那个无限循环二进制数的,只能存一个四舍五入(准确说应该是零舍一入,毕竟是二进制)后的近似值,所以即引入了有效精度这一概念。

(1)对于float类型:由于尾数部分位数是固定的小数点后23位,23位所能表示的最大数是2^23−1=8388607,所以十进制的尾数部分最大数值是8388607,也就是说尾数数值超过这个值之后,float将无法精确表示,所以float最多能表示小于8388607的小数点后7位,但绝对能保证的为6位,也即float的十进制的精度为为6~7位。

(2)对于double类型:double数据类型的推算过程和上述同理,唯一的区别在于尾数由23位扩展到52位,阶码由8位增加到了11位,计算方法不变。所以double的阶码(移码表示)为1~2046,偏移量为1023,故指数范围为-1022~1023,得表示范围为(2^1023*2)~(-2^1023*2)即为-1.7E+308~1.7E+308,绝对值最小可以取到2^-1022,精度则为2^52-1=4503599627370495,为16位。所以精度最高位16位,一定可以保证15位。

 

posted @ 2021-01-21 10:57  outthinker  阅读(1263)  评论(0编辑  收藏  举报