首先我们先来看一下下面这段代码。
通过对比①与③所打印出来的结果,可以知道浮点型和整型数据在内存中的存储方式并不相同。这里我们将浮点数float_n转化为(-1)^S*M*2^E这种形式来观察。
- 其中(-1)^S表示符号位,如果S=0,则表示该浮点数为正数;当S=1时,浮点数为负数。
- M为有效数字,M大于等于1,小于2
- 2^E表示指数位
所以十进制的5转化为二进制就是101.0,按照上面所说的进行转化,就是1.01*2^2;十进制的-5转化后就是-1.01*2^2。
接下来我们再来看一下小数,比如5.5,因为0.5等于2的-1次方,所以将5.5转化为二进制就是101.1,再用刚才的公式进行转化,其结果就是(-1)^0*1.011*2^2。
通过上面式子的转换,我们就知道了S,E,M的大小,那么我们就可以将这些数据存储了,它们的存储方式就如下图所示。
前面说过1≤M<2,所以m的整数位总为1,因此规定在存储M的时候可以将m暂时舍去,只保存小数部分,等到使用时再把它加上,这样我们就能多存储一位了。
至于E我们这里将他看做一个无符号数,那么肯定会有人疑问,当E为负数时,肯定就会出现问题了呀。因此IEEE 754规定:存入内存E的真实值必须要加上一个中间数,对于8位数的E,中间数为127,11位的E,中间数为1023。就比如8bit的E真实值为1,那么存入的就是128,如果真实值是-1,那么存入的就是126。
我们用5.0这个数来验证一下③
既然存入了E,那么我们在使用时肯定也需要将其拿出来,而这又分为了三种情况
- E不为全0或全1,这种情况我们就可以按存入时相反的操作取出
- E为全0,此时E不再加上之前所舍去的1,而是还原为0.xxx的小数,这种情况表示±0或是很小的数字
- E为全1,这时如果M全为0,那么表示±无穷大
这样我们就能知道②打印全为0的原因就是E全为0了。