自学者疑难之一,实型数在计算机中的存储方式


    由于关于实型数介绍的资料很少,同时介绍的资料描述得都很简短,各种专业教程中都是
简单带过,没有具体的讲解.这样的情况下只好边参考资料边进行逆向分析,经过分析验证后
得出以下结论并整理成文档。虽然编写程序时可以不关心它的存储方式,编译器可以自动进
行转换,但在许多情况下了解它的存储方式却是个关键。以下的分析目的都旨在于:
"知其然,知其所以然".

读懂本文所需的前提是了解[补码]

实型数的表示,根据IEEE(14)标准分析如下

一.先将浮点数转换为二进制数并进行规格化.
    
    1.转换为二进制并规格化一个数时将其调整为大于等于1而小于2,存储时隐含掉整数部分只保留尾数;

        如(这部分可以只了解下):

         10进制数12
         10进制转2进制为:   12 = 1100 ;
         1100 规格化后为:   1.1 * 2^3这样一个表达式(等同于对1.1左移位3次),2^3 表示2的3次方.
          
          12 : 是正数既符号位为0. 存到符号字段中  
          2^3: 3就是阶码.         存到阶码字段中
          1.1: .1是尾数.          存到尾数字段中         
          "1.1"中的整数"1"不需要存储,只存储尾数
          
          如果是0.111这样的二进制数码则调整为 1.11 * 2^-1 .
          即阶码 = -1;
          尾数   = 11;
          

         数值"12"存储为float的结果是:
         (数据结构图)
         为了对齐行列,各表示: A:符号; B:移码阶; C:尾数.
         |  A  |     B    |            C              |
         |  0  | 10000010 | 1000000 00000000 00000000 |
         
         关于B:移码阶部分一定会让人比较迷惑,这里可以先不用管,这部分重点放在第二大段中介绍.

    2.浮点数中尾数的二进制转换及规格化
        浮点数尾数部分。
            通常的转换方式可以转换得出(如除2求余法),但进一步整理下思路可以使后文
        更易于理解.
        以10进制数:27.4375为例,它们的关系是(书上直接抄来的例子):
        
        A冥        B权      C数码      D数值(10进制)

        A  2^4  2^3  2^2  2^1  2^0  2^-1  2^-2   2^-3    2^-4

        B  16   8    4    2    1    0.5   0.25   0.125   0.0625

        C  1    1    0    1    1  . 0     1      1       1        11011.0111(2进制)

        D  16 + 8  + 0 +  2  + 1  + 0  +  0.25 + 0.125 + 0.0625   = 27.4375
 
二.在机器中的存储方式

以float来做分析,存储中位的顺序由高到低描述是: 

float  符号位1bit;阶码位8bit;尾数23bit.共计32bit 即 4 byte长度.

符号位:
    标识数的正负符号,1表示(-)

阶码部分:

    由于是8bit;阶为2。因此2的8次方 = 256个描述信息
    规范中,数的表示法有些特别,使用偏移量方式计算。

    表示方法为: 阶的偏移量 E_Disp = 127 = (256/2 -1)
                阶码为E表示为 存储方式[e] = E + E_Disp
    所以,使用存储方式[e]来计算时需要在之上减去E_Disp,
    即: E = [e] - E_Disp

    此阶码的特点:
            这种表示法形式实为补码,但这种表示法不同于普通补码.它使用偏移量计算,
        偏移量即补码,同普通补码的区别是末位不进行加1修正. 

            这种表示法中因为0不应该存在负数,而又没有普通补码表示法的修正,所以
        存储0时全存为0

            同时这样的方法带来一个额外的空间,原因是表示 (+-)127 的情况下范围
        为:127*2 = 254 实际可用范围为256,0占用1个范围,(+-)127占用254的范围,这
        样就是:256-(127*2 + 1) = 1。但是这个描述信息并没有被浪费,它在IEEE(14)
 
 
2 自学者疑难之一,实型数在计算机中的存储方式 
         规范中用于表示无穷大即:∞。这种方式下无穷表示为:阶码部分全为1,尾码部分
        全为0,符号位标识 (+- ∞).
        
    综合说明:
            1.阶码存储为: 阶码 + 偏移量127;
            2.被存储的数值为0时不进行任何形式的转换,将其全存为0,符号位唯一确定为0;
            3.被存储的数值为+-无穷时阶码位全存为1,尾数位全存为0,符号位表示+-;
             
尾数部分:

    可以倒回去看第一大段的例子.

额外的说明与思考:

        这种形式是一种科学标识法其起源很早,但鄙人才疏学浅无从追寻根源,这种形
    式只为此方式的一种。进一步了解该方法是将来解决许多问题的捷径写出能解决特殊
    问题的算法的基础。后面紧接着就更深入的分析下去。

        已提到这是一种科学标识方法,它并不局限于IEEE标准,它的实际形式是:

        |符号位|阶码符号位|阶码|尾数|

        这个形式在 "阶码"和"尾数" 的长度上并没有数理上的限制,特殊场合里可以进行
    自定义.这里不是说在编写程序的时候可以不理会IEEE的标准了,那取决于当前的开发
    环境,在机器上使用标准开发环境时是必须严格遵守IEEE标准的,这是一个规范,否则就
    要放弃环境的默认处理,改为自己用算法来处理数的转换及计算.

        也就是说如果使用了自己定义的数据,那如cpu 的 ADD 指令等不能再直接使用来进
    行对它的处理了,因为计算机的数据格式是遵循IEEE标准的.这段话看起来有点让人觉得
    废话,但我觉得有必要强调一下,以免误与他人.    

        而,这就是关于这一小段"额外"存在的理由.根据这个实际形式可以定义自己的浮点
    数,用它来实现超大体积的浮点数、定点数的存储及计算,也或是超小体积.
       
        继续就IEEE的标准做进一步说明与分析:
        
        在前一小节的分析中没有关于"阶码的符号位"的描述. 

        然,偏移量为127 ;     127 = 1111111 (占用7bit). 

        偏移量 + 阶码的结果为正数会达到8bit宽,负数则只会小于8bit宽,因为阶码以补码
    形式存储,那获得阶码必有一个计算过程即减去E_Disp,结果就是正数或负数,所以实际上
    已经不需要阶码正负符号位或可以说成是:1表示正数;0表示负数.
     
        到这里,我补充进来的目的应能让人很清楚了.这只是一种储存方式,必要的时候可
    以不受限制的搬来灵活运用,自定义数据结构.

double型:
double 8byte 符号位1bit;阶码位11bit;尾数52bit
除了偏移量的不同即: 阶的偏移量 E_Disp = (2048/2 -1),其它的相同. 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值