类型float大小为4字节,即32位,内存中的存储方式如下:
- 最高位 31 位 ,保存符号位 S,“0”表示正数 ,“1”表示负数
- 第30 位~23 位 ,共 8 位 ,保存指数部分(指数值加上偏移量127) ,称为阶码
- 第22 位~0 位 ,共 23 位 ,保存系数部分 (整数位的1不保存),称为尾数
类型double大小为8字节,即64位,内存布局如下:
- 最高位 63 位 ,保存符号位 S,“0”表示正数 ,“1”表示负数
- 第 62 位~52 位 ,共 11 位 ,保存指数部分(指数值加上偏移量1023) ,称为阶码
- 第 51 位~0 位 ,共 52 位 ,保存系数部分 (整数位的1不保存),称为尾数
如,十进制浮点数2.5的二进制形式为10.1,转换为科学计数法形式为 (1.01)∗(21) ( 1.01 ) ∗ ( 2 1 ) ,由此可知指数为1,尾数(即科学计数法的小数部分)为01。
根据浮点数的存储标准(IEEE制定),float类型指数的起始数为127(二进制0111 1111),double类型指数的起始数为1023(二进制011 1111 1111),在此基础上加指数,得到的就是内存中指数的表示形式。尾数则直接填入,如果空间多余则以0补齐,如果空间不够则0舍1入。所以float和double类型分别表示的2.5如下(二进制):
符号位 : 0
指数 : 1000 0000
尾数 : 010 0000 0000 0000 0000 0000
符号位 : 0
指数 : 100 0000 0000
尾数 : 0100 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
特别说明:
以单精度浮点数为例,单精度浮点数的指数部分所能表达的实际指数的范围是-126~+127,指数部分是-126~+127加上127 ,指数值的大小从1~254(0和255是特殊值)。浮点小数计算时,指数值减去偏正值将是实际的指数大小。
如果浮点数的指数部分的编码值是0,尾数为非零,那么这个浮点数将被称为非规约形式的浮点数。IEEE 754标准规定:非规约形式的浮点数的指数偏移值比规约形式的浮点数的指数偏移值大1。例如,最小的规约形式的单精度浮点数的指数部分编码值为1,指数的实际值为-126;而非规约的单精度浮点数的指数域编码值为0,对应的指数实际值也是-126而不是-127。实际上非规约形式的浮点数仍然是有效可以使用的,只是它们的绝对值已经小于所有的规约浮点数的绝对值;即所有的非规约浮点数比规约浮点数更接近0。
除此之外还有3个特殊值:
- 如果 指数 是0 并且 小数部分 是0, 这个数是±0 (和符号位相关)
- 如果 指数 = 2e−1 2 e − 1 (e为阶码的位数)并且 小数部分 是0, 这个数是 ±无穷大 (同样和符号位相关)
- 如果 指数 = 2e−1 2 e − 1 并且 小数部分 非0, 这个数表示为不是一个数(NaN)
形式 | 指数 | 小数部分 |
---|---|---|
零 | 0 | 0 |
非正规形式 | 0 | 非0 |
正规形式 | 1~ 2e−2 2 e − 2 | 任意 |
无穷 | 2e−1 2 e − 1 | 0 |
NaN | 2e−1 2 e − 1 | 非0 |