1. 浮点数据在内存的表示形式
在二进制科学表示法中,S=M*2^N 主要由三部分构成:符号位+阶码(N)+尾数(M)。
对于float型数据,其二进制有32位,其中符号位1位,阶码8位,尾数23位;
对于double型数据,其二进制为64位,符号位1位,阶码11位,尾数52位。
31 30-23 22-0
float 符号位 阶码 尾数
63 62-52 51-0
double 符号位 阶码 尾数
符号位:0表示正,1表示负
阶码:这里阶码采用移码表示,对于float型数据其规定偏置量为127,阶码有正有负,对于8位二进制,则其表示范围为 -128-127,double型规定为1023,其表示范围为-1024-1023。比如对于float型数据,若阶码的真实值为2,则加上127后为 129,其阶码表示形式为10000010
2. 浮点数字节大小
sizeof(double) = 8;
sizeof(float) = 4;
3. 强制转换:float->double; double->float. 它们不是简单的字节截断或扩展,而是根据对方的内存存储形式进行转化。举例如下, 更详细的举例请参见附录测试程序。
double da=3,da1; // da在内存的形式为: 0x40 08 00 00 00 00 00 00
float fa= 3,fa1; // fa在内存的形式为: 0x40 40 00 00
da1 =(double) fa; // float->double得到da1: 为0x40 08 00 00 00 00 00 00
fa1 = (float) da; // double->float得到da2: 为0x40 40 00 00
4. printf 和 scanf 对浮点数据的操作。
读取float数据:scanf("%f", &fa); 接收一个float型数据,并且存放在以&fa为起始地址的4个字节内存中,不管fa是什么类型。
读取double数据:scanf("%lf",&db);接受一个double型数据,并且存放在以&db起始地址的8个字节内存里,不管db是什么类型。
输出double/float数据都为:printf("%f,%f",&fa,&db);在printf内部都自动转换为double类型。
附录:测试程序
#in clude <stdio.h>
#include <string.h>
typedef union
{
double n;
float y;
unsigned char c[8];
}uni_u;
int main()
typedef union
{
double n;
float y;
unsigned char c[8];
}uni_u;
int main()
{
int i=0;
double d=0;
uni_u aa={.n=0},bb={.n=0},cc={.n=0};
printf("please print a float value:");
scanf("%f",&aa);
printf("the value in the memory is:\n");
for(i=0;i<8;i++)
{
printf("%x\t",aa.c[i]);
}
printf("\n");
printf("%f\n",aa.n);
printf("%f\n\n",aa.y);
d=(double)aa.y;
memcpy(&aa,&d,8);
printf("the float to double value:\n");
for(i=0;i<8;i++)
{
printf("%x\t",aa.c[i]);
}
printf("\nplease input a double value:");
scanf("%lf",&bb);
for(i=0;i<8;i++)
{
printf("%x\t",bb.c[i]);
}
printf("\n");
printf("%f\n",bb.n);
printf("%f\n\n",bb.y);
float f=(double)bb.n;
printf("the double to float value:\n");
memcpy(&bb,&f,8);
for(i=0;i<8;i++)
{
printf("%x\t",bb.c[i]);
}
}
输出:
please print a float value:3
int i=0;
double d=0;
uni_u aa={.n=0},bb={.n=0},cc={.n=0};
printf("please print a float value:");
scanf("%f",&aa);
printf("the value in the memory is:\n");
for(i=0;i<8;i++)
{
printf("%x\t",aa.c[i]);
}
printf("\n");
printf("%f\n",aa.n);
printf("%f\n\n",aa.y);
d=(double)aa.y;
memcpy(&aa,&d,8);
printf("the float to double value:\n");
for(i=0;i<8;i++)
{
printf("%x\t",aa.c[i]);
}
printf("\nplease input a double value:");
scanf("%lf",&bb);
for(i=0;i<8;i++)
{
printf("%x\t",bb.c[i]);
}
printf("\n");
printf("%f\n",bb.n);
printf("%f\n\n",bb.y);
float f=(double)bb.n;
printf("the double to float value:\n");
memcpy(&bb,&f,8);
for(i=0;i<8;i++)
{
printf("%x\t",bb.c[i]);
}
}
输出:
the value in the memory is:
0 0 40 40 0 0 0 0 //1.说明:float在内存中的形式,只占用了前面4字节
0.000000
3.000000
the float to double value:
0 0 0 0 0 0 8 40 //2. 说明:上述float值转化为double类型,内存情况。
please input a double value:3
0 0 0 0 0 0 8 40 //3. 说明:double类型,内存情况。与上述2值相同。
3.000000
0.000000
the double to float value:
0 0 40 40 0 0 0 0 //4. 说明double值转化为float型,可知内存和上述1值相同。