开始学习浮点数在内存中的存储、取出的小伙伴们,相信已经知道了整型也就是int的存储方式,首位为符号位,以及原、反、补码的转换,这里就不做过多叙述了。
思路
既然说想要知道浮点数在内存中的存储方式,C语言又是面向过程的编程语言,这里我们可以拿浮点类型和整形取地址互相转换输入做对比,来观察其中的变化过程
实例
在这里我们分别用整形存入内存的方式存入一个整形数据后,以浮点数类型的取出方式来取出该地址的数据;再以浮点数存入内存的方式存入一个浮点数后,以整形取出的方式来取出该地址的数据。此时,我们来看看两个特殊存储、取出的输出值。
此时我们可以看到两个值都不是想象中的正常输出
根据这两个输出我们可以判断浮点数和整形的存储、取出方式肯定都是有区别的,那么,浮点数的存储、取出方式是什么呢
知识点讲解
为了了解浮点数的存储、取出方式,需要知道浮点数的值是如何计算出的,然后反推
在这里,先将a=9的二进制序列写出来:00000000...01001,在这里,我们加上小数点后的二进制,小数点后一位为2^-1(2的负1次方),后两位为2^-2,依此类推......*b=9.00的二进制序列则为:00000000...01001.00;把1的最高位开始往后取,即1001.00,为了方便,我们使这个值恒大于等于1,小于2;这里缩进为1.00100,因为是二进制,所以1001.00=1.00100*2^3,而最高位的符号位则可以以-1^0来表示, 即*b=-1^0 * 2^3 * 1.00100
这里以一个表达式来表示浮点数*b的值:*b=-1^S * 2^E * M,接下来将这个表达式分解解释一下。
S即是二进制的最高位即符号位,以-1^S表示,当S为0时,-1^0为1,S为1时,-1^1为-1,所以S表示浮点数的符号;,E即为二进制数缩进到1.xxxxxx时缩进的位数,二进制把E当作2的指数即可;M即为缩进后的值1.xxxxxx
那么float浮点数的S、E、M在内存中实际上的存储方式是什么呢,依旧是画图给大家说明,为了使浮点数表示的范围更大,所以在存储时减去首位固定的1,存储能多一个bit,所以在取出时加1
double类型为8个字节64bit,所以double的S=1位,E=11位,M=52位,同时,还有一项规定,即E在存入时需要加上127,即加上01111111,取出时也要减127。所以最终9.00的二进制存储为
取出时存入的E-=127,M+=1
存储时E加127就会涉及到两种特殊情况:1.E在存储时全为0,则E=-126(或double-1022),有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数,这样做时为了表示±0,以及接近于0的很小的数字
2.E全为1,这时如果有效数字M全为0,表示±无穷大
最后举个例子float a =5.5;则a=-1^0 * 2^2 * 1.011; S=0,E=2,M=1.011,实际存储时E=2+127,M=1.011-1,二进制为01000000101100000000000000000000,转化为16进制0x40b00000