目录
浮点数在内存中存储的方式和整型不一样。所以我们在存储的时候,尽量避免把整型保存为浮点型或者 浮点型保存为整型。
1、浮点数的存储方式
下面通过两个浮点数来了解浮点数的存储过程,这两个浮点数仅仅是比较方便介绍。
(1) 转化为二进制
整数位 5 转化为二进制就是 101
小数位 0.5,化为二进制就是0.1
- 十进制里,0.1表示的是 1/10;0.01表示的是 1/100
- 类似的,二进制里,0.1表示的是 1/2;0.01表示的是 1/4
因此,5.5 转化为二进制就是 101.1
(2) 转化为国际标准形式
根据国际标准IEEE(电气和电子工程协会)754,任意一个二进制浮点数V可以表示成下面的形式:
- (-1)^S * M * 2 ^ E
- (-1)^S 表示符号位,当s=0,V为正数;当s=1,V为负数。
- M表示有效数字,1 ≤ M < 2.(M 是一个二进制小数,终归还是二进制,必须小于2)
- 2^E表示指数位。
101.1 使用二进制科学计数法的形式,可以写成 1.011 * 2^2(现在是二进制,所以底数要换成2,而不是10)。因为5.5是一个正数,所以最终可以写成
(-1)^0 * 1.011 * 2^2
此时 S = 0
M = 1.011
E = 2
因此,浮点数就使用S、M、E来存储
(3) 使用国际标准形式存储
单精度可以理解成 float类型,双精度可以理解成 double类型
================= S = 0 =================
S 可以直接存入,存入S的值是 0
================= E = 2 =================
E 是 8位,如果将第一位作为符号位,取值范围会小很多;但是如果无符号位,E可以是负数,这样的话就无法表示E。因此,IEEE 754规定,E在存入之前必须要加上一个中间数,如果是单精度,就加上127;如果是双精度,就加上1023。
所以 实际存入E 的值是 2+127 = 129 = 1000 0001
================= M = 1.011 =================
在第二点说明 M 的时候,有提到一句话,1 ≤ M < 2。由于 M 是二进制(除了1就是0),所以M的整数位一般都是 1,存一个确定的比特位进去,只是占用空间。因此,IEEE 754规定,M仅存小数位进去。
所以实际存入 M 的值是 001,由于M有23位,缺省部分默认补 0 。
综上,实际存入的浮点数的二进制形式是
0 10000001 01100000000000000000000
转换成十六进制就是
40 B0 00 00
(4) 存储方式验证
下面我们使用VS来验证在内存中的存储方式是否如上所说
这里的VS使用的是小端存储,左边是低地址,右边是高地址
所以写成我们熟悉的形式就是 40 b0 00 00
2、从内存中取出浮点数需满足的规则
S 可以直接取出来,M 取出来的时候需要加上最开始的整数位 1。
但是E 取出的来的时候,就需要分情况了,因为存入的时候,不能保证一定是以浮点数的形式存入,如果是以整型的方式存入,E是什么,我们也无从得知。
(1) E 不全为0 或 不全为1
这个时候就属于一般情况,直接使用取出来的 E 减去127或者1023,实际看取出来的时候,是以单精度还是以双精度取出来。
(2) E 全为 0
此时如果按照正常取法,那就是 -127,这个时候就会变成
± 1.xxxxxx * 2^(-127)
这种情况下得到的浮点数几乎接近 0 ,因此我们返回的结果为
0.00000000...000
(3) E 全为 1
如果按照正常取法,那就是 127,这个时候就会变成
± 1.xxxxxx * 2^(127)
这种情况下的浮点数要么是正无穷,要么是负无穷。