zoukankan      html  css  js  c++  java
  • 【转载】浮点数在内存中的存储格式

    浮点数在内存中的存储格式  

    2010-10-09 11:03:28|  分类: C/C++编程基础|字号 订阅

     
     
    由一个程序开始

    int _tmain(int argc, _TCHAR* argv[])
    {
        float a = 1.0f;//浮点数在内存中是以符号+指数+尾数保存的

        cout<<(int&)a<<endl;//1.0f在内存中的保存的是0x3f800000,将a地址开始的sizeof(int)个字节当做int类型的输出106535216

        int b = 0x3f800000;
        cout<<b<<endl;//106535216

        cout<<(int)a<<endl;//1

    }

    浮点数:
         浮点型变量在计算机内存中占用4字节(Byte),即32-bit。遵循IEEE-754格式标准。一个浮点数由2部分组成:底数m 和指数e。

        ±mantissa × 2exponent
    (注意,公式中的mantissa 和 exponent使用二进制表示)
       底数部分 使用2进制数来表示此浮点数的实际值。
       指数部分 占用8-bit的二进制数,可表示数值范围为0-255。
       指数应可正可负,所以IEEE规定,此处算出的次方须减去127才是真正的指数。所以float的指数可从 -126到128
       底数部分实际是占用24-bit的一个值,由于其最高位始终为 1 ,所以最高位省去不存储,在存储中只有23-bit。
       到目前为止, 底数部分 23位加上指数部分 8位使用了31位。那么前面说过,float是占用4个字节即32-bit,那么还有一位是干嘛用的呢? 还有一位,其实就是4字节中的最高位,用来指示浮点数的正负,当最高位是1时,为负数,最高位是0时,为正数。

       浮点数据就是按下表的格式存储在4个字节中:

        Address+0 Address+1 Address+2 Address+3

       Contents SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM
       S: 表示浮点数正负,1为负数,0为正数
       E: 指数加上127后的值的二进制数
       M: 24-bit的底数(只存储23-bit)

       注意:这里有个特例,浮点数为0时,指数和底数都为0,但此前的公式不成立。因为2的0次方为1,所以,0是个特例。当然,这个特例也不用认为去干扰,编译器会自动去识别。

    举例1:计算机存储中的二进制数如何转换成实际浮点数
       通过上面的格式,我们下面举例看下-12.5在计算机中存储的具体数据:
       Address+0 Address+1 Address+2 Address+3

       Contents 0xC1 0x48 0x00 0x00
       接下来我们验证下上面的数据表示的到底是不是-12.5,从而也看下它的转换过程。

       由于浮点数不是以直接格式存储,他有几部分组成,所以要转换浮点数,首先要把各部分的值分离出来。

       Address+0 Address+1 Address+2 Address+3

       格式 SEEEEEEE EMMMMMMM MMMMMMMM MMMMMMMM

       二进制 11000001 01001000 00000000 00000000

       16进制 C1 48 00 00

        可见:

        S: 为1,是个负数。

        E:为 10000010 转为10进制为130,130-127=3,即实际指数部分为3.

        M:为 10010000000000000000000。这里,在底数左边省略存储了一个1,使用实际底数表示为 1.10010000000000000000000

        到此,我们吧三个部分的值都拎出来了,现在,我们通过指数部分E的值来调整底数部分M的值。调整方法为:如果指数E为负数,底数的小数点向左移,如果指数E为正数,底数的小数点向右移。小数点移动的位数由指数E的绝对值决定。

        这里,E为正3,使用向右移3为即得: 1100.10000000000000000000 至次,这个结果就是12.5的二进制浮点数,将他换算成10进制数就看到12.5了,如何转换,看下面:

       小数点左边的1100 表示为 (1 × 23) + (1 × 22) + (0 × 21) + (0 × 20), 其结果为 12 。

       小数点右边的 .100… 表示为 (1 × 2-1) + (0 × 2-2) + (0 × 2-3) + ... ,其结果为.5 。

       以上二值的和为12.5, 由于S 为1,使用为负数,即-12.5 。

       所以,16进制 0XC1480000 是浮点数 -12.5 。

    举例2:浮点数装换成计算机存储格式中的二进制数。
       举例将 17.625换算成

    float型。
       首 先,将17.625换算成二进制位:10001.101 ( 0.625 = 0.5+0.125, 0.5即 1/2, 0.125即1/8 如果不会将小数部分转换成二进制,请参考其他书籍)
       再将 10001.101 向左移,直到小数点前只剩一位成了 1.0001101 x 2的4次方(因为左移了4位)。此时我们的底数M和指数E就出来了:
       底数部分M,因为小数点前必为1,所以IEEE规定只记录小数点后的就好,所以此处底数为 0001101 。

       指数部分E,实际为4,但须加上127,固为131,即二进制数 10000011 符号部分S,由于是正数,所以S为0.
       综上所述,17.625的 float 存储格式就是: 0 10000011 00011010000000000000000 转换成16进制:0x41 8D 00 00 所以,一看,还是占用了4个字节。

    double在内存中的保存,double是8个字节64位,其中最高位63位是符号位,1表示该数为负,0正;62-52位,一共11位是指数位;51-0位,一共52位是尾数位。

    按照IEEE浮点数表示法,下面将把double型浮点数38414.4转换为十六进制代码。  
              把整数部和小数部分开处理:整数部直接化十六进制:960E。小数的处理:  
      0.4=0.5*0+0.25*1+0.125*1+0.0625*0+……  
              实际上这永远算不完!这就是著名的浮点数精度问题。所以直到加上前面的整数部分算够53位就行了(隐藏位技术:最高位的1  
       
      不写入内存)。  
              如果你够耐心,手工算到53位那么因该是:38414.4(10)=1001011000001110.0110101010101010101010101010101010101(2)  
      科学记数法为:1.001……乘以2的15次方。指数为15!  
              于是来看阶码,一共11位,可以表示范围是-1024   ~   1023。因为指数可以为负,为了便于计算,规定都先加上1023,在这里,  
       
      15+1023=1038。二进制表示为:100   00001110  
              符号位:正——   0   !  
              合在一起(尾数二进制最高位的1不要):  
      01000000   11100010   11000001   11001101   01010101   01010101   01010101   01010101  
              按字节倒序存储的十六进制数就是:  
      55   55   55   55   CD   C1   E2   40   


    详细出处参考:http://www.itqun.net/content-detail/122840_2.html
  • 相关阅读:
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车按键启动和蜂鸣器报警
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车指定花式动作
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车指定花式动作
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车指定花式动作
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车前后左右综合实验
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车前后左右综合实验
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车前后左右综合实验
    asp中设置session过期时间方法总结
    asp中设置session过期时间方法总结
    ASP.NET关于Session_End触发与否的问题
  • 原文地址:https://www.cnblogs.com/tangqs/p/2741192.html
Copyright © 2011-2022 走看看