诸如3.14159和6.023x1023这样的数值无法按照整数存储。C语言为了存储这种数值,就有了float、double、long double浮点数类型。
内存中的浮点数
浮点数在内存的存储方式为:符号位、指数、尾数。
float与double类型的数据在计算机内部的表示法是相同的,但由于所占存储空间的不同,其分别能够表示的数值范围和精度不同。
浮点数存储示例
浮点数的转换
1. 将浮点数转换成二进制
2. 用科学计数法表示二进制浮点数
3. 计算指针偏移后的值
注意:计算指数时需要加上偏移量,而偏移量的值与类型有关
示例:对于指数6,偏移后的值
float:127 + 6 -> 133
double: 1023 + 6 -> 1029
10进制浮点数的内存表示
实数8.25在内存中的float表示
1.8.25的二进制表示:1000.01 -> 1.00001 * (2 ^ 3)
2.符号位:0
3.指数:127 + 3 -> 130 -> 1000 0010
4.小数:0000 1
内存中8.25的float表示为:
1.0 1000 0010 0000 1000 0000 0000 0000 000 -> 0x4104 0000
示例代码:10进制浮点数的内存表示
#include <stdio.h>
int main ()
{
float f = 8.25 ;
unsigned int * p = (unsigned int *)& f;
printf ( "0x%08X\n" , *p );
return 0 ;
}
输出结果:
0x41040000
这也说明了:浮点类型和整数类型的数据存储方式不同。
浮点数的不精确表示
问题:
int类型的范围:[-231, 231 -1]
float类型的范围:[-3.4 * 1038, 3.4 * 1038]
那么int和float都占4个字节的内存,为什么float却比int的范围大得多呢?
浮点数的秘密
- float能表示的具体数字的个数与int相同
- float可表示的数字之间不是连续的,存在间隙
- float只是一种近似的表示法,不能作为精确数使用
由于内存表示法相对复杂,float的运算速度比int慢得多
注意:double与float具有相同的内存表示法,因此double也是不精确的。由于double占用的内存较多,所能表示的精度比float高。
示例代码:float类型的不精确表示
#include <stdio.h>
int main ()
{
float f = 3.1415f ;
float fl = 123456789 ;
printf ( "%0.10f\n" , f );
printf ( "%0.10f\n" , fl );
return 0 ;
}
输出结果
3.1414999962
123456792.0000000000