目录
三、国际标准IEEE754规定的二进制浮点数在内存中的存储方式
一、浮点型成员
//float
//double
//long double
二、浮点型数据长度
printf("% d\n", sizeof(float));//输出:4;
printf("% d\n", sizeof(double));//输出:8;
printf("% d\n", sizeof(long double));//输出:8;
三、国际标准IEEE754规定的二进制浮点数在内存中的存储方式
//float类型和int类型,虽然内存同样为4个字节,但是整型和浮点型数据在内存中的存储方式是不同的;
3.1二进制浮点型的表示形式
//根据国际标准IEEE(电气和电子工程协会)754,任意一个二进制浮点数可以表示为以下形式:
(-1)^S*M*2^E
(-1)^S 表示符号位,当S=0,V为正数;当S=1,V为负数;
M表示有效数字,大于等于1,小于等于2;
2^E 表示指数位;
//示例:float V = 9.5f 转化为二进制数,再转换为科学计数法,再转换为IEEE754标准;
(1)整数部分:整数 9 可以转换为 1001
(2)小数部分:
//小数转二进制:
将小数 0.5 转化为二进制数,小数点后一位的二进制比重为 2^-1 ,即 2^-1 = 1/2^1 = 1/2 =0.5 ,所以当二进制数小数点后一位为 1 时,即表示十进制数的 0.5 ;9.5 的二进制数为:1001.1
//二进制转科学计数法:
将二进制1001.1 转换为科学计数法,小数点向右移动,得到 1.0011*2^3 ,基数2为进制,^3为小数点向右移动了多少位;
//科学计数法转IEEE754标准:
将科学计数法1.0011*2^3 转换为IEEE754标准:(-1)^S*M*2^E = (-1)^0*1.0011*2^3 ;
//另外,在小数转二进制的二进制数计算上,还有一种比较简便的方法:
如,将小数 0.6 乘 2 ,得数取其整数位,即小数 0.6 * 2 =1.2 ,取整数 1 作为小数后第一位;再将1.2的小数部分*2,获得第二个数,即0.2 * 2=0.4,取整数 0 作为下一位;依此类推;
3.2IEEE754规定:
//任意一个二进制浮点数可以表示为以下形式:
(-1)^S*M*2^E
对于32位的浮点数,最高的1位是符号位s,之后8位为指数E,余下23位为有效数字M;
对于64位的浮点数,最高的1位是符号位s,之后11位为指数E,余下52位为有效数字M;
//其中符号位S
S为1表示负数,为0表示正数;
//其中有效数字M
对于有效数字M,在计算机内部保存M时,默认该数第一位总是1,因此可以被舍去,只保存后面的小数部分;如M为1.001,则计算机只保存001;在读取该数时,再把第一位的1加上去,以此节省1位有效数字;
//其中指数E
对于指数E,规定E为无符号整数(unsigned int),即如果E为8位,取值范围则为0~255,如果E为11位,取值范围则为0~2047;但在科学计数法中,指数E是可以出现负数的,因此根据IEEE754规定,存入内存时E的真实值必须再加上中间数,对于8位E,中间数为127,对于11位E,中间数为1023;如2^10,E为10,保存为32位浮点数时,将被保存为10+127=137,即10001001;
对于指数E,在读取时,如果E不全为0或全为1,则将指数E的计算值减去127(或1023)得到真实值,再将有效数字M前加上第一位的1;
对于指数E,在读取时,如果E全为0,则浮点数的指数E等于1-127(1-1023),即为真实值;此时,有效数字M不再加上第一位的1,二十还原为0.xxxxxx的小数,这样做是为了表示±0,以及接近于0的很小的数字;
对于指数E,在读取时,如果E全为1,则表示±无穷大;
3.3练习:通过以下题目理解浮点数在内存中的存储
int main()
{
int n = 9;
//0000 0000 0000 0000 0000 0000 0000 1001 -- 9的原码
//0000 0000 0000 0000 0000 0000 0000 1001 -- 9的补码
//0000 0000 0000 0000 0000 0000 0000 1001 -- int类型 n 的补码
float* pFloat = (float*)&n;
printf("n的值为:%d\n", n);//输出结果为:9;
printf("*pFloat的值为:%f\n", *pFloat);//输出结果为:0.000000;
//根据浮点数对 int类型 n 的补码 的解读;
//S = 0 = 正数 ;E = 00000000 = -126 ;M = 0.00000000000000000001001 ;
//读出结果为:+0.00000000000000000001001*2^-126 ,即 0.000000 ;
*pFloat = 9.0;
//1001.0 -- 9.0 的二进制数
//(-1)^0*1.001*2^3 -- 1001.0 的科学计数法
//S = 0 ;E = 130 ;M = 1.001 ;
//0 10000010 00100000000000000000000000 -- 浮点数 9 的32位存储
printf("*pFloat的值为:%f\n", *pFloat); //输出结果为:9.000000;
printf("n的值为:%d\n", n);//输出结果为:一个极大的数;
//int 类型对浮点数的解读;
//0100 0001 0001 0000 0000 0000 0000 0000 -- 数字 1091567616
return 0;
}
四、浮点型数据的取值范围
//浮点型数据的取值范围包含在头文件 <float.h> 中;
//float
printf("%f\n", -FLT_MAX);//最小值;
printf("%f\n", FLT_MIN);//最小非负值(无限接近于0);#define FLT_MIN 1.175494351e-38F // min normalized positive value
printf("%f\n", FLT_MAX);//最大值;#define FLT_MAX 3.402823466e+38F // max value
//double
printf("%lf\n", -DBL_MAX);//最小值;
printf("%lf\n", DBL_MIN);//最小非负值(无限接近于0);#define DBL_MIN 2.2250738585072014e-308 // min positive value
printf("%lf\n", DBL_MAX);//最大值;#define DBL_MAX 1.7976931348623158e+308 // max value
//long double
printf("%llf\n", -LDBL_MAX);//最小值;
printf("%llf\n", LDBL_MIN);//最小非负值(无限接近于0);#define LDBL_MIN DBL_MIN // min normalized positive value
printf("%llf\n", LDBL_MAX);//最大值;#define LDBL_MAX DBL_MAX // max value
(--end--)