浮点数:分三部分存储
sign(符号位)
exponent(指数位)
fraction(尾数位)
根据IEEE存储规范 32bit 、64位浮点数分别如下
float类型 | 1bit_sign | 8bit_exponent | 23bit_fraction |
double类型 | 1bit_sign | 11bit_exponent | 52bit_fraction |
sign | exponent | fraction |
符号位 | 指数部分 | 尾数部分 |
1位 | A:8位 B:11位 | A:23位 B:52位 |
0表示正数 1表示负数 (二进制的值) | A:指数值+127即为二进制存储的值 B:指数值+1023即为存储的值 | 从高位到低位存储 |
(显然,二进制的科学计数法,只需要指数部分和尾数部分值,整数部分是可忽略,因为它总是为 1)。
备注:A:表示float B: 表示double
举个例子
浮点数:11.35
实数部分:11 二进制值: 1 0 1 1
短除法从十进制转二进制(从后往前取二进制的值)
小数部分:0.35 二进制值:0 1 0 1 1 0 0 1 1 0 (0110循环)
0.35 * 2 = 0.7 ---> 0 (取整数部分 0,以下类同取整数部分)
0.7 * 2 = 1.4 ---> 1 (取上次的小数部分继续乘以2,以下类同)
小数部分(fraction) | 乘以2的值 | 取积的整数 | 取积的小数部分做下一次的循环操作,直到乘以2的积的小数部分为0 | |
0.35 | 0.7 | 0 | ||
0.7 | 1.4 | 1 | ||
0.4 | 0.8 | 0 | ||
0.8 | 1.6 | 1 | ||
0.6 | 1.2 | 1 | ||
0.2 | 0.4 | 0 | ||
0.4 | 0.8 | 0 | 待续。。。反复乘到小数为0 |
小数部分从上往下合并,得到:1011.01 0110 0110 ...(0110循环,特意书写分割开)
这个值用科学计数法表示就是:1.011 01 0110 0110...
指数为3(二进制11),小数为011 01 0110 0110 ...(循环)
注意,fraction区域就是直接存储小数部分的值,但是指数不是。
因为exponent区域在float里是8位,也就是能表示256个值,但它并不是表示0~255,而是-127~128, 这是IEEE规定的。
(显然,需要支持指数为负数的情形)
所以这里的exponent区域的值是指数3加127即130,最终exponent的二进制值:1000 0010
1bit_SIGN 符号位
1bit SIGN 符号位 | 8bit exponent 指数位 | 23bit fraction 尾数位 |
0 | 1000 0010 | 01101 0110 0110... |
(注意,float存储11.35可能存在精度丢失问题,最好用double存储来查验结果)
double存储下来的十六进制为:0x4026 b333 3333 3333
再举个简单例子,验证下
3.75, 转为二进制是11.11,科学表示法,1.111
指数为1, 小数为0.111
最后存储值: 0100 0000 0111 0000 0000 0000 0000 0000
十六进制为:0x4070 0000