根据IEEE二进位浮点数算术标准(IEEE 754),一个二进制浮点数应表示为:
Value = sign * exponent * fraction;
试图翻译成人话就是:
浮点数的实际值 = 符号位 * 指数偏移值 * 分数值
继续试图解析该公式:
V = ( - 1 )^S * M * 2^E;
来点说明:
- V指浮点数的值;
- S指该浮点数的符号,当 S = 0 时,该浮点数为正,当 S = 1 时,该浮点数为负;
- M指该浮点数的有效数字;
- E指该浮点数的阶数。
float类型占用4个字节,即32位,我们规定第1位来存储S,第2-9位存储E,第10-32位存储M;
double类型占用8个字节,即64位,第1位存储S,第2-12位存储E,第13-64位存储M。
如果仍然没有看太懂的话,非常正常,因为此处需要举个栗子。
例:十进制数-12.0以二进制浮点数存储。
首先把十进制化为二进制
-12.0 ---> -1100.0
按照浮点数的表示公式写出该数字
-1100.0 = ( - 1 )^1 * 1.100 * 2^3
即 S = 1 ,M = 1.100 ,E = 3;
关于M的补充规则:
此处我们看到M(有效数字) = 1.100,有效数字是一个从第一个不为0的数 字开始的数,故M的小数点左边必定为1,所以在我们的规则中,省略了这个1以节省空间,只存储小数点后面的数字,在这个例子中,M存储的数字为100。
关于E的补充规则:
由于E是一个无符号整数,若E为8位,则取值范围为[0,255],若E为11位,则取值范围为[0,2047]。但实际上我们知道科学计数法是允许指数出现负数的,故IEEE 754规定,E的值需要减去一个中间值(即127或1023)之后才等于我们通过公式求得的值,在这个例子中,以float类型为例,E存储的数字为3 + 127 =130。
综上所述得到S = 1 ,M = 100 ,E = 130;
最后一步进制转换,以float类型为例:
- S(占1位) = 1 --->1;
- E(占8位) = 130 --->1000 0010;
- M(占23位) = 100 ---> 000 0000 0000 0000 0110 0100;
于是,在以上规则下,-12.0得以被表示出来,即:
1 1000 0010 000 0000 0000 0000 0110 0100
关于E的特殊情况说明:
- 当E的二进制表示全为0时,此时V直接表示为无穷小量,没错就是高数中的那个无穷小。趋近于0。
- 当E的二进制表示全为1时,此时V直接表示为无穷大量,符号取决于S的值,没错就是高数中的那个无穷大。