浮点数在内存中的存储方式为:
符号位、指数、尾数。
float和double类型的数据在计算机内部的表示法是相同的,但是由于所占的内存空间不同,其分别能够表示的数值范围和精度不同。
浮点数的转换:
1、将浮点数转换成二进制;
2、用科学计数法表示二进制浮点数;
3、计算指数偏移后的值。
注意:计算指数的时候需要加上偏移量,而偏移量的值与类型有关。
float类型: 127 + 6 -> 133
double类型:1023 + 6 ->1029
示例:实数8.25在内存中的float表示:
8.25的二进制表示:1000.01 -> 1.00001*(2^3)
符号位:0
指数:127+3=130 = 10000010;
小数:00001
所以,内存中8.25得float表示为:
0 100 0001 0 000 0100 0000 0000 0000 0000 -> 0x41040000
运行下面代码,验证结果:
#include<stdio.h>
int main()
{
float a = 8.25;
unsigned int* p = (unsigned int *)&a;
printf("0x%08X\n", *p);
return 0;
}
delphi@delphi-vm:~/will$ ./a.out
0x41040000
int类型的范围【-2^31, 2^31-1】
float类型的范围【-3.4*10^38, 3.4*10^38】
int和float都占四个字节,为什么float比int表示的范围大得多呢?
原因在于,float能表示具体数据的数字和int相同,但是float可表示的数字之间不是连续的,存在间隙,所以float只是一种近似的表示法,不能作为精确数使用。
由于内存表示法相对复杂,float的运算速度比int慢很多。
需要注意的是:double和float都具有相同的内存表示法,但是由于double占用的内存较多,所能表示的精度比float高。
示例:观察下面代码,判断输出:
#include<stdio.h>
int main()
{
float a = 3.1415f;
float b = 123456789;
printf("%0.10f\n", a);
printf("%0.10f\n", b);
return 0;
}
在linux Gcc下编译运行结果为:
delphi@delphi-vm:~/will$ ./a.out
3.1414999962
123456792.0000000000
输出值与原值并不相同,只是一种近似表示法。
所以我们需要注意的是,由于浮点数与整数类型的内存表示法不同,而且浮点数的内存表示更加复杂,所以在表象上浮点类型可表示的数据范围更大,但是不精确,且运行速度较慢。