什么是浮点数?浮点数是一种数值表达方式,用于表示实数,即包含小数点的数字。浮点数由两部分组成:尾数和指数,尾数表明数字的精度和大小,指数表明数字的大小范围。
根据国际标准IEEE(电气电子工程师学会)754,任意一个二进制浮点数V可以表示成下面的形式:
V=(-1)^S*M*2^E
(-1)^S表示符号位,当S=0时,V为正数;S=1时,V为负数
M表示有效数字,M是大于等于1,小于2的
2^E表示指数位
例如:
十进制浮点数5.5,转为二进制是101.1,相当于1.011*2^2。
按照上面V的格式,可以知道S=0,M=1.011,E=2。
同理十进制浮点数-5.5,其二进制为-101.1。则S=1,M=1.011,E=2。
IEEE 754规定:
对于32位的浮点数,最高的1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字M
32位float类型浮点数内存分配图
对于64位的浮点数,最高的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M
64位float类型浮点数内存分配图
浮点数存储过程:
对于每一位M来说,都有1<=M<2,也就是说每一个M都可以写成1.xxxxx……的形式,因此,我们可以把小数点前面的1省略(不在M中存储小数点前面的1),再将小数点后面的数存入M。比如1.011*2^2,只把小数点后面的011存入M中。这样就可以多出一位bit来存储小数点后面数字,使精度提高。
E是一个无符号整数,即E>=0。但是,有时算出来的E可能是负数,如1.0*2^-1,E=-1,不符合原理。所以所以IEEE 754规定,存⼊内存时E的真实值必须再加上⼀个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。例如2^3的E为3,因此保存为32位浮点数时,保存内容为3+127=127,即10000010
求出下面代码的结果。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
int n = 9;
float* pFloat = (float*)&n;
printf("n的值为:%d\n", n);
printf("*pFloat的值为:%f\n", *pFloat);
*pFloat = 9.0;
printf("num的值为:%d\n", n);
printf("*pFloat的值为:%f\n", *pFloat);
return 0;
}
9的补码为0 00000000 00000000000000000001001
printf("*pFloat的值为:%f\n", *pFloat)表示将整数9的补码当成浮点数在内存中的存储,则S=0, E=0-127=-127,M=00000000000000000001001,即(-1)^0*1.00000000000000000001001*2^-127
而2^-127表示一个极小的数,因此结果显示为0.000000
9.0在内存中的存储为0 10000010 001000000000000000000000
printf("num的值为:%d\n", n)表示将浮点数9.0在内存中的存储当成整数的补码,因此
010000010 001000000000000000000000所对应的十进制数为1091567616