我们知道,对于整数,它在内存中是以二进制补码的形式存储的。

如果通过整数的存储形式,上述代码运行结果是9 9.000000 9 9.000000
结果并非如此,我们可以知道,浮点数和整数的存储形式是不同的。
根据国际标准IEEE(电气和电子工程协会)754,任意一个二进制浮点数V可以表示成下面的形式:
V=(-1)^s*M*2^E (-1)^s表示符号位,当s=0时,V为正数;当s=1时,V为负数。 M表示有效数字,M时大于等于1,小于2的。 2^E表示指数位。
首先要将浮点数写成二进制形式
比如,十进制的5.0,写成二进制就是101.0,相当于1.01*2^2(科学计数法)。
这样,按照上面V的格式,可以得出s=0,M=1.01,E=2。
同理,十进制的-5.0,写成二进制是-101.0,相当于-1.01*2^2。
s=1,M=1.01,E=2;
IEEE 754规定:
对于32位的浮点数(float),最高的一位存储符号位s接着的8位存储E,剩下的23位存储有效数字M 对于64位的浮点数(double),最高的一位存储符号位s,接着的11位存储E,剩下的52位存储有效数字M


浮点数在存的过程中,实际上是存s M E.
IEEE 754规定,在存M的时候,因为M是大于等于1,小于2的,所以默认M的第一位总是1,所以在存储的时候,总是舍去1,保存小数部位,而等到取的时候,再将1加上即可。这样做的目的,是为了节省一位有效数字。以32位浮点数为例,M只可以存23位,舍去后,M可以存24位。
至于指数E,情况比较复杂。
首先,E是一个无符号整数(unsigned int)
这意味着,如果E位8位,它的范围为0~255;如果E位11位,它的范围是0~2047。然而在科学计数法中,E是有可能出现负数的,所以IEEE 754规定,在存储的时候,E的真实值必须加上一个中间数,对于8位来说,加上127;对于11位来说,加上1023。比如2^10,E是10,必须保存成127+10=137,即10001001
指数E从内存中取出,还可以分为3种情况。
1,E不全为0或不全为1
在取的过程中,指数E的值减去127或(1023),再将有效数字M前加上第一位的1.
比如0.5的二进制表示形式为0.1,写成科学计数法为1.0*2^(-1),其中s=0,M=1.0,E=-1;
E存储的值为-1+1227=126,表示为01111110,而M去掉1为0,23为存储0,s=0,第一位则存储0,
则其二进制形式为0 00000000000000000000000 01111110
2,E全为0
这时,浮点数的E就等于1-127或1-1023,这时有效数字M不再加上第一位的1,表示成0.xxxxx的小数,这样这个数就是接近于0的一个很小的数字。
3,E全为1
这时,如果有效数字M全为0,则表示是一个正负无穷的数字。
这时,我们再看最初的代码。

对于整形9来说,它的二进制表示形式为00000000 00000000 00000000 00001001。
而在*pFloat视角,它认为存储的是一个浮点数,这个浮点数的E全为0,真实的E是1-127=-126,认为它是一个很小接近于0的数字,所以打印出的结果是0.000000。
*pFloat=9.0,写成二进制形式为1001.0,科学计数法表示为1.001*2^3,可以得出E=3,M=1.001,s=0,E的存储值为127+3=130,130的二进制形式为10000010,所以9.0在内存中会存储形式为
0 10000010 00100000000000000000000
对于n来说,他会把0 10000010 00100000000000000000000当成一个二进制数字打印,结果就是1091567616.