Summary
1)浮点数在内存中的存储方式:
类型 | 符号位 | 指数 | 尾数 |
---|---|---|---|
float | 1位(第31位) | 8位(第23-30位) | 23位(第0-22位) |
double | 1位(第63位) | 11位(第52-62位) | 52位(第0-51位) |
2)float与double类型的数据在计算机内部的表示法是相同的
,但是由于所占存储空间大小的不同
,其分别能够表示的数值范围和精度不同
。
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进制的形式来打印内存里的值
4)float能表示的具体数字的个数与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位) |
float与double类型的数据在计算机内部的表示法是相同的
,但是由于所占存储空间大小的不同
,其分别能够表示的数值范围和精度不同
。
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进制表示为:0xc1040000
float 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慢的多
另:double和float的内存表示法是相同的,所以也是不精确的。由于double占用的字节数比float多,所以double表示的精度比float高。
float f1 = 3.1415f;
float f2 = 123456789;
// 打印小数点后10位
printf("%0.10f\n", f1); // 3.1414999962
printf("%0.10f\n", f2); // 123456792.0000000000
本文总结自“狄泰软件学院”唐佐林老师《C语言进阶课程》。
如有错漏之处,恳请指正。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。