浮点数小数部分二进制转换,:原始数据的小数部分,乘2,取整数部分,去整数部分,然后再乘2,再取整数部分,去整数部分,再乘2......如此循环,直到小数部分值为0(包括此时的取整值)或者小数部分跟原始小数部分相等为止(包括此小数部分的取整值)。然后将取到的整数值顺序排下来就是此小数部分的二进制表示。
例:5.75
0.75 * 2 = 1.5 》1
0.5 * 2 = 1.0 》1
此时的1.0的小数部分为0,停止。所以5.75的小数部分的二进制表示为 .11,合起来5.75的二进制表示就是101.11
将101.11转换成十进制:101.11 = 1*2^2 + 0*2^1 + 1*2^0 + 1*2^-1 + 1*2^-2 = 5.75
3.2
0.2 * 2 = 0.4 》 0
0.4 * 2 = 0.8 》 0
0.8 * 2 = 1.6 》 1
0.6 * 2 = 1.2 》 1
此时的1.2的小数部分跟原始数据的小数部分相等,停止。所以3.2的二进制表示就是11.0011
然后就很明显,11.0011的真实值并不等于3.2:1*2^1 + 1*2^0 + 0*2^-1 + 0*2^-2 + 1*2^-3 + 1*2^-4 = 3.1875。
此时,就要说到浮点数的精度问题,通过查询微软文档,发现float类型的精度为:1.192092896e-07,double类型的精度为:2.2204460492503131e-016,这就代表着,实际电脑中储存值3.2并不是11.0011,它可能是11.0011001100110011......直到这个数的精度符合它的类型所要求的精度。
浮点数在内存中的存放,以5.75(float类型),也就是101.11为例,float类型一般占4个字节,也就是32个位。
(大端)第1个位为符号位,0为正,1为负;所以5.75的符号位为0
接着8个为指数位,8个位最多可以表示2^8个数,即256。但指数也有正负,所以计算机就会先将那个8个位看成是一个无符号的char类型,然后根据无符号char类型,将其读出来,范围为255~0,然后将得到的数值减去127,此时它的范围就会变成128~-127了。所以,就有了float类型的取值范围了:2^128 ~ 2^-127。所以,在读float类型的指数位时,就先把它当成无符号的char类型去读,然后减去127,就是实际的指数值了。
最后剩下的23位,为尾数位,也就是格式化后的二进制数,即:0111,但有23位,所以后面需要补上0,所以尾数位就为:0111 0000 0000 0000 0000 000
所以,最后就可以写出来5.75在内存中实际的存储值:0 1000 0001 0111 0000 0000 0000 0000 000
double类型跟float类型类似,总共有8个字节,64位,1位符号位,11位指数位,52位尾数位。