第3课 - 浮点数的秘密

第3课 - 浮点数的秘密

1. 浮点数在内存中的存储方式

    

float与double类型的数据在计算机内部的表示法是相同的,但由于所占存储空间的不同,其分别能够表示的数值范围和精度不同

2. 浮点数的转换

2.1 浮点数的转换方法

如何将十进制的浮点数转换为内存中二进制表示的浮点数呢?按照下面三个步骤:

    ① 将浮点数转换为二进制

    ② 用科学计数法表示二进制浮点数

    ③ 计算指数偏移后的值(需要加上偏移量,float型:指数 + 127,double型:指数 + 1023)

比如对于指数6,float型偏移量就为 127 + 6 = 133,double型偏移量为1023 + 6 = 1029

2.2 浮点数的转换示例

下面以十进制的 8.25 演示一下上述的转换方法。

    ① 将8.25转换为二进制(注意小数的二进制表示方法)    ==>  1000.01

    ② 用科学计数法表示1000.01(注意这里是二进制,2^3)   ==>  1.00001(2^3)

    ③ 指数3偏移后为:127 + 3 = 130

所以浮点数8.25对应的符号位、指数、尾数分别为:

    符号位:0

    指数:130 ==> 10000010

    小数:00001   // 要将小数转为尾数,需要在后面补0

8.25在内存中的二进制表示为:0 1000 0010 000 01000000 0000 0000 0000 = 0x41040000

下面我们写代码验证一下:

 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5     float f = 8.25;
 6     unsigned int *p = (int *)&f;
 7 
 8     printf("f = 0x%08x\n", *p);
 9 
10     return 0;
11 }

结果和我们前面分析的相同。

    

3. 浮点数的秘密

 我们知道int型数据占用4个字节,表示的范围为:【-231 , 231-1】;float型也占用4个字节,表示的范围为:【-3.4*1038,3.4*1038】。

看到这里不少人很奇怪,4个字节按照排列组合能表示的数据范围应该是固定的,为什么float类型表示的范围却比int型的大?这里我们就要揭露一下float类型的秘密了。

(1)float能表示的具体数值的个数与int型相同,因为都是4字节,排列组合都是232-1

(2)之所以float表示出来的范围比int型大,是因为float可表示的数字之间是不连续的,数据之间存在跳跃

(3)float只是一种近似的表示法,不能作为精确数使用

(4)由于float类型的内存表示方法相对复杂,float的运算速度比int慢很多

※ 因为double与float具有相同的内存表示法,所以double也是不精确的。由于double占用的内存较多,所能表示的精度比float高。

【float类型的不精确示例】

 1 #include<stdio.h>
 2 
 3 int main()
 4 {
 5     float f1 = 3.1415f;
 6     float f2 = 123456789;
 7  
 8     // 精确到小数点后面的10位
 9     printf("%0.10f\n", f1);    // 3.1414999962  ==>  不等于3.1415,表示的结果是不精确的
10     printf("%0.10f\n", f2);    // 123456792.0000000000  ==>  与123456789不相等,表示的数据是不连续的、跳跃的
11 
12     return 0;
13 }

 

再添加0.25和1.25的转换方法,加深理解:

0.25

    ① 0.25 转换为二进制 0.01

    ② 二进制0.01用科学计数法表示 1.0*(2^-2),指数为 -2 + 127 = 125

    ③ 小数为0

所以0.25在内存中表示为:0  01111101  00000000000000000000000 = 0x3e800000

1.25

    ① 1.25转换为二进制 1.01

    ② 二进制1.01用科学计数法表示1.01*(2^0) ,指数为 0 + 127 = 127

    ③ 小数为0.25

所以1.25在内存中表示为:0  01111111  01000000000000000000000 = 0x3fa00000

 

posted @ 2019-11-13 22:36  Hengs  阅读(468)  评论(0编辑  收藏  举报