我们这期文章讨论浮点数在内存中的存储方式。
我们以单精度浮点数(float)为例,它占用的内存为4字节。
根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:(-1)^S * M * 2^E ,其中(-1)^S表示符号位;M表示有效数字,大于等于1,小于2;2^E表示指数位。
按照上述规则这样,计算机就可以知道三个数值并且计算出我们需要的那个浮点数了。以为他们三个数值是一个整体,我们就需要把他们存放在一段连续的空间,那么在内存中这个数值的存储形式就是下图这样
继续以单精度(float)为例,
符号位只需要一个比特位就可以表示正负,所以符号位占用大小位一个bit。当S为0表示正数S为1表示负数。举个例子例如-1.0
剩余的31个bit位留给有效数字和指数位。单精度浮点数(float)的有效数字占用23个bit位,指数位占用了8个bit位;8字节的双精度浮点数(double)的有效数字占用52个bit位,指数位占用11个bit位。
指数位(E)和有效数字位(M)均视为无符号整数
(-1)^S * M * 2^E 有效数字(M)是大于1小于2的数字。这样的话就又出现了不必要的浪费。聪明的科学家干脆把有效数字的整数部分默认为1内存中只保留小数部分例如1.011******,内存中存储的无符号数值为011******(实际上是20位*),很巧地又为存贮节约了1个bit位的空间。
比如5.0转换为2进制是0101。根据公式,(-1)^S * M * 2^E 。S为0;M则为1.01;E则为2。整数1省略那么在内存中就应该是
关于指数位,我们知道了它占用了无符号的8bit位那么他的取值是0~255,然而实际需求中指数是存在负数的情况的,聪明的科学家规定存入内存的指数的真实值必须加上一个中间数,对于float(8bit位)是127,对于double(11bit位)这个值为1023。例如二进制浮点数0.1转化成公式{(-1)^S * M * 2^E}(-1)^0*1*2^(-1)
这时指数位(E)的值就是 真实值(-1)+中间数(127)=(存入内存的值)126。
126转换为二进制
接下来我们来做一个练习例如浮点数5.5
实际上并不是全部浮点数都能完全的转化成为二进制数例如1.3,转换以后只能接近十进制的1.3。