浮点数的存储规则:
二进制浮点数V可表示为以下形式:
(-1)^S*M*2^E
float-单精度浮点型:
double-双精度浮点型:
补充:有一些数在内存中无法以浮点型精确保存(如3.3,小数点后总会差一点无法完全保存,只能无限接近)
这就是浮点数会丢失精度的原因。
M中存储的只有小数点后的数字(因为每个数字中都是1......所以都有1,省略小数点前的1)。
E中存储的是无符号数,若为8位,取值范围是0~255;若为11位,取值范围是0~2047。
规定存入内存时,E的真实值必须再加上一个中间数,若为8位,+127;若为11位,+1023。
比如:2^10时E为10,保存为32位浮点数时,必须保存为10+127=137,即10001001。
E从内存中取出还可以分为三种情况:
1.E不为全0或不为全1时,怎么存进去,怎么取出来,反推。
2.E为全0,规定指数E等于1-127(或1-1023)为真实值,有效数字M前不再加1,而是还原成 0.xxxx的小数,这样是为了表示±0以及接近于0的很小的数字。
3.E为全1,如果有效数字M全为0,表示±∞大的数字(±取决于S)。
例子解析:
int main()
{
int n = 9;
//00000000000000000000000000001001 - 9的补码(整数原反补相同)
float* pFloat = (float*)&n;
printf("n的值为:%d\n", n);
printf("*pFloat的值为:%f\n", *pFloat);
//浮点型从内存中取出时:
//9表示为
//0 00000000 00000000000000000001001
//(-1)^0 * 0.00000000000000000001001 * 2^-126
//最后打印0.000000因为太小了后面的看不见
*pFloat = 9.0;
//9.0
//1001.0
//(-1)^0 * 1.001 * 2^3
//0 10000010 00100000000000000000000
printf("n的值为:%d\n", n);
//浮点型放进去,以整形取出来,要将上面的0 10000010 00100000000000000000000看为补码
//即01000001 00010000 00000000 00000000
//第一位为0,为正数,原反补相同
//直接转换为十进制为1091567616
printf("*pFloat的值为:%f\n", *pFloat);
//浮点型放进去,以浮点型取出来,反推为9.000000
return 0;
}
//整数和浮点数在内存中的存储方式不一样