浮点数的秘密
浮点数的秘密#
内存中的浮点数##
浮点数在内存中的存储方式为:符号位,指数,尾数
类型 | 符号位 | 指数 | 尾数 |
---|---|---|---|
float | 1位(第31位) | 8位(第23-30位) | 23位(第0-22位) |
double | 1位(第63位) | 11位(第52-62位) | 52位(第0-51位) |
浮点数的转换##
-
将浮点数转换成二进制
-
用科学计数法表示二进制浮点数
-
计算指数偏移后的值
注意:计算指数时需要加上偏移量,而偏移量的值与类型有关
例如:对于指数6,偏移后的值如下:
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表示:
- 010000010 00001000000000000000000 -----> 0x41040000
10进制浮点数的内存表示
编程验证上面的计算:
#include <stdio.h>
int main(int argc, char const *argv[])
{
float f = 8.25;
unsigned int *p = (unsigned int *)&f;
printf("0x%08x",*p);
return 0;
}
结果与计算的一致
一个有趣的问题##
-
int 类型的范围:[-231,231-1]
-
float 类型的范围:[-3.4 * 10^38,3.4 * 10^38]
思考:
int 和float都是占有四个字节的内存,为什么表示的范围不同呢?
-
float能表示的具体数字的个数与int相同
-
float可表示的数字之间不是连续的,存在间隙
-
float只是一种近视的表示法,不能作为精确数使用
-
由于内存表示法相对复杂,float的运算速度比int慢得多
实例:float类型的不精确性
#include <stdio.h>
int main(int argc, char const *argv[])
{
float f = 3.1415f;
float fl = 123456789;
printf("%0.10f\n",f);
printf("%0.10f\n",fl);
return 0;
}
结果:
总结:
-
浮点数与整数的内存表示法不同
-
浮点数的内存表示更加的复杂
-
浮点数可以表示的范围更大
-
浮点数是一种不精确的类型
-
浮点数的运算速度较慢