【C进阶】3、浮点数的秘密
Summary
1)浮点数在内存中的存储方式:
类型 | 符号位 | 指数 | 尾数 |
---|---|---|---|
float | 1位(第31位) | 8位(第23-30位) | 23位(第0-22位) |
double | 1位(第63位) | 11位(第52-62位) | 52位(第0-51位) |
表示法是相同的
,但是由于所占存储空间大小的不同
,其分别能够表示的数值范围和精度不同
。【【C进阶】3、浮点数的秘密】3)浮点数的转换
如:浮点数-8.25的二进制转换,float类型:
1. 符号位
:1(负数)2. 绝对值二进制
:1000.01(整数部分的指数依次为0,1,2...;
负数部分的指数一次为-1,-2,-3...)3. 科学计数法
:1.00001 * 23
,指数为34. 指数+偏移
:3 + 127
= 130 <--> 1000 0010(float的指数占8位
)5. 尾数
:尾数部分为00001,占23位,不足的后面补0
:00001 0000 0000 0000 0000 006. 最终
:二进制为:1 1000 0010 00001000000000000000000(符号位 + 指数 + 尾数);用16进制表示为:0xc1040000注意
:- 对于float类型,指数的偏移为
+127
;对于double类型,指数的偏移为+1023
。尾数部分,不足的位数后面补0
。 - 通过如下
指针
方式,可以获得一段内存中的二进制位
unsigned int* p = (unsigned int*)&val; printf("%08x", *p); // %08x表示以16进制的形式来打印内存里的值
具体数字的个数与int相同
(都占用4个字节,一共32个bit位,所以最多就232种排列组合方式
,即最多能表示232个数)5)float的表示法是
不精确
的,所以能表示的范围比int大。由于float的值不精确,所以对于一个float值,直接打印的数据可能有偏差
;同时对于浮点数的运算,不能直接和0比较
。6)因为float的
内存表示法比int复杂
,所以float的运算速度
比int慢
。浮点数的秘密 1、浮点数在内存中的存储方式
类型 | 符号位 | 指数 | 尾数 |
---|---|---|---|
float | 1位(第31位) | 8位(第23-30位) | 23位(第0-22位) |
double | 1位(第63位) | 11位(第52-62位) | 52位(第0-51位) |
表示法是相同的
,但是由于所占存储空间大小的不同
,其分别能够表示的数值范围和精度不同
。2、浮点数的转换 如:浮点数-8.25的二进制转换,float类型:
1. 符号位
:1(负数)2. 绝对值二进制
:1000.01(整数部分的指数依次为0,1,2...;
负数部分的指数一次为-1,-2,-3...)3. 科学计数法
:1.00001 * 23
,指数为34. 指数+偏移
:3 + 127
= 130 <--> 1000 0010(float的指数占8位
)5. 尾数
:尾数部分为00001,占23位,不足的后面补0
:00001 0000 0000 0000 0000 006. 最终
:二进制为:1 1000 0010 00001000000000000000000(符号位 + 指数 + 尾数);用16进制表示为:0xc1040000float f = -8.25f;
// f指明为float类型
unsigned int* p = (unsigned int*)&f;
// 用指针指向该浮点数的内存,并'以无符号整型数来表示'
printf("0x%08X\n", *p);
// %08X,表示以16进制大写的形式来打印值,通常'用来打印内存的二进制位'// 输出为:0xC104 0000,和笔算结果一致。
如果已知一个32位二进制表示一个浮点数,则推算结果和上面相反
3、浮点数深入理解 int类型的范围:[-231, 231-1]
float类型的范围:[-3.4 x 1038, 3.4 x 1038]
问题:为什么int和float都占用4个字节的内存,而float却比int的范围大的多呢?
解析:
- float能表示的
具体数字的个数与int相同
(都占用4个字节,一共32个bit位,所以最多就232种排列组合方式
,即最多能表示232个数) - float可表示的数字之间是不连续的,有间隙的
- float只是一种
近似
的表示法,不能作为精确数来使用 - 由于内存表示法相对复杂,float的
运算速度
比int慢的多
float f1 = 3.1415f;
float f2 = 123456789;
// 打印小数点后10位
printf("%0.10f\n", f1);
// 3.1414999962
printf("%0.10f\n", f2);
// 123456792.0000000000
本文总结自“狄泰软件学院”唐佐林老师《C语言进阶课程》。
如有错漏之处,恳请指正。
推荐阅读
- 宽容谁
- 我要做大厨
- 增长黑客的海盗法则
- 画画吗()
- 2019-02-13——今天谈梦想()
- 远去的风筝
- 三十年后的广场舞大爷
- 叙述作文
- 20190302|20190302 复盘翻盘
- 学无止境,人生还很长