• 第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
    ", *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
    ", f1);    // 3.1414999962  ==>  不等于3.1415,表示的结果是不精确的
    10     printf("%0.10f
    ", 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

  • 相关阅读:
    发送短信验证(防刷新)
    JsRender 学习总结
    JsRender (js模板引擎)
    jQuery中ready与load事件的区别
    web端图片文件直传
    2018面对对象_作业三
    2018面对对象_作业二
    2018面对对象_作业一
    2018寒假作业_4(自我总结)
    2018寒假作业_3(电梯版本二)
  • 原文地址:https://www.cnblogs.com/shiwenjie/p/11853817.html
Copyright © 2020-2023  润新知