本文将介绍计算机中四种编码: 原码,补码,反码,移码的有关知识。   


   计算机需要处理的信息包括数值信息以及各种符号,文字,图像语言等信息。但计算机内部的硬件只能表示两个状态0和1,计算机只能对二进制的数字信息进行传送、处理。加工和存储,因此,在计算机的内部,各种信息都必须经过数字化编码后才能被传送加工和处理,必须对这些信息进行编码。
   各种数值数据在计算机中的表示的形式成为机器数,其特点是采用二进制计数制,数的符号用0、1表示,小数点则隐含表示而不占位置。机器数对应的实际数值称为数的真值。小数点位置固定的数称为定点数,有无符号数和带符号数之分。计算机中的定点数只采用纯整数或者纯小数形式。
   无符号数表示正数,在机器数中没有符号位。对于无符号数,若约定小数点的位置在机器数的最低位后,则是纯整数;若约定小数点的位置在机器数的最高位之前,则是纯小数。
   对于带符号数,n位机器数的最高位Xs是表示正负的符号位,其余n-1位则表示数值。若约定小数点的位置在机器数的最低数值位之后,则是纯整数,若约定小数点的位置在机器数的最高位之前(符号位之后),则是纯小数。
  
           带符号定点整数格式: Xs  Xn-2 - - - X1 X0 .
           
           带符号顶点小数格式: Xs. Xn-2 - - - X1 X
             
           ("."为小数点位置)

1.原码表示

   原码(true form)是最容易理解的一种数据编码表示,也称“符号-数值”表示法。  
   数值X的原码记为[X],如果机器字长为n(即采用n个二进制位表示数据),则最高位是符号位,0表示正号,1表示负号,其余n-1位表示数值的绝对值。数值0的原码表示有两种形式(假设n=8):

        [+0]=0 0000000,[-0]=1 0000000

   由于小数点约定的位置不同,计算机中的数据分为定点小数和定点整数,相应由两种形式的原码定义。

   定点小数的原码定义如下:
   
                 [X]= X          ,   0<=X<1

                       1-X=1+|X|   ,  -1<X<=0

  
   式中X表示真值,[X]表示真值X的原码。若X为正,则[X]与X相同;因为X为纯小数,且0<=X<1,所以最高位(符号位)为0,若X为负,则[X]为1+|X|,即最高位(符号位)为1,数值位为X的绝对值。课间原码体现了数据的绝对值,因此在乘除运算中常采用原码。

   定点整数的原码定义如下:

                 [X]= X        ,           0<=X<2
n-1

                       2n-1-X=2n-1+|X|  ,    -2n-1<X<=0


   例:若机器字长n=8
   [+35]=(00100011)2
   [-35]=27-(-35)=(10000000)2+(00100011)2=(10100011)2

   
[+0.8125]=(0.1101000)2

   [-0.8125]=1-(-0.8125)=(1.0000000)2+(0.1101000)2=(1.1101000)2

由定义可以得出原码的如下性质:
1.原码表示法用最高位表示符号位,符号位为0表示正,1表示负。数值部分就是原来的数值,即绝对值的真值。
2.真值0在原码表示中不唯一。由定义,[+0]=0 0000000,[-0]=1 0000000
3.假设机器字长为n,则
    ·原码表示的定点小数,其表示范围为: -(1-2-(n-1))~+(1-2-(n-1))
    ·原码表示的定点小数,其表示范围为:-(2n-1-1)~+(2n-1-1)

4.对于定点小数,当X>0时,0<[X]<1,当X<0时,1<[X]<2
  对于n为定点整数,当X>0时,0<[X]<2n-1,当X<0时,2n-1<[X]<2n.
  因此,负数的原码大于整数的原码。
5.由真值转换为原码,可将正数的符号位写0,负数符号位写1,数值位照写即可;由原码转换为真值,则将符号位0写成"+",1写成"-",数值位不变即可。

                     + <--->0 ,- <---->1
           真值X <----------------------------->[X]
                           数值位不变

   原码的优点:表示简单直观,机器数和真值间的相互转换很容易。用原码实现乘,除运算的规则很简单,可取其绝对值(原码的数值部分)直接运算,并遵循同号相乘除结果符号为正,异号为负的原则,单独处理符号位。
   缺点:实现加减运算较为复杂。




2.补码表示


补码概念的引入:

      -3 = +9 ( MOD 12 )
      一个负数可以表示成一个正数对于一个数M的补数。

补码的定义:

设模为M,一个n为二进制数X的补码的一般定义为:

                 [X]= M + X  (M为2n)

上式是一个包含正负数在内的统一定义式。
·若X>0,则模作为超出的部分将被舍去,[X]=X,因而正数的补码就是其本身。
·若X<0,则[X]=M-|X|,[X]就是|X|以M为模的补数。

定点小数的补码定义如下:

           [X]=  X=[X]      ,0<=X<1  
  
                  2+X = 2-|X|  ,-1<=X<0    (MOD 2).

定点整数的补码定义如下:


           [X]= X = [X]    ,      0<=X<2
n-1

                 2n+X =2n-|X|   ,   -1<=X<0       (MOD 2)


例: 设机器字长为8位

    [-35]补=28+(-35)=(1 0000 0000)2-(0010 0011)2=(1101 1101)2
    
    [-0.8125]=2+(-0.8125)=(10.0000000)2-(0.1101000)2=(1.0011000)2

·补码的性质:

1.补码的符号位。

当0<=X<1时,[X]=X,因此有0<=[X]<1,可见[X]的形式必然为0.xxxx...x,所以符号位S=0。

当-1<=X<0时,[X]=2+X,因此有1<=[X]<2,可见[X]的形式必然为1.xxxx...x,所以符号位为S=1。
2.补码中0的表示

[0]=0,0的补码是唯一的,因此X与[X]一一对应。

3.补码的表示范围
假设字长为n,则用补码表示定点小数,其范围为 -1<=X<=+(1-2-(n-1)),用补码表示定点整数,范围为 -2-(n-1)<=X<=+(2n-1-1).

4.负数的补码值大于整数的补码值。

5.补码与真值、原码之间的相互转换。

   当真值X>=0时,
                        + <-------> 0
           真值X  <----------------------------------> [X]=[X]
                         数值位不变


   当真值X<0时,假设机器字长为n,由定义得:

   [X]=2+X=1.111111..1 + X + 0.000000..1=1.111111..1-|X| +0.00000...1
              n个1                    n-1个0          |X|按位取反          末位+1  
   
由此可以得到负数X转换为补码的规则如下:将|X|的真值按位取反,末位+1。

   反过来,由定义[X]=2+X,得 -X=2-[X],又因为 -X=|X|,因此有

   |X|= -X=2-[X]=1.1111..1-[X]+0.00000..1
                          [X]按位取反       末位+1

   而真值 X=-|X|,由此得出将负数X的补码[X]转换为真值X的规则如下:将负数的补码转换为真值时,只需将符号位写为负号"-",补码的各位按位取反,末位+1即可。

   当真值X<0时,
                         "-"  <------->1
              真值X  <----------------------------------->[X]
                          数值按位取反,末位加1


   当真值X<0时,
                            符号位1不变
              [X]<------------------------------------>[X]
                         数值按位取反,末位加一

 
另一种原码转换为补码的简便方法:数值部分自低位向高位搜索,第一个1以及其右的各位0保持不变,第一个1左边的各位按位取反。

证明:设数值部分为 X X X... X 1 0..00
              _ _ _   _
按位取反后为:   X X X...X 0 1..11
              _ _ _   _
末位+1:       X X X...X 1 0..00


·补码的符号位扩展:

在实际应用的过程中,有时需要扩充补码的位数。

1.要将n位纯小数补码变成2n位,只需在末尾添加n个0即可。

  这个很好理解,例如[X]=0.0000001---->0.000000100000000

2.要将整数补码的模扩大 2n 倍,只需将[X]的符号位向左复制n位即可。

 证明: [X1]=2n+X ---> X=[X1]-2n;

       [X2]=22n+  X   --->[X2]= 22n+  [X1]-2n
 
                 将X代入

=2n·2n+ [X1]-2=(2n-1)·2n    +     [X1]
   合   并          
  n-1个1左移n位        加上[x1]补

·补码的算术右移(除2运算)

    算术右移就是除2运算,即已知[X]补,求[X/2]补。

                          符号位不变
    结论:  [X]补 ---------------------------------->[X/2]

                         按位右移一位


    证明:   若X>=0

           [X]补 = X ----> X/2= [X]/2,
           
           [X/2]补 =[X]/2;       即X>=0时补码右移1位
      
           若X<0  
 
           [X]=2n+X --->X=[X]-2n,--->X/2=[X]/2-2n-1

           [X/2]= 2+  X/2 = 2n + [X]/2 - 2n-1  = 2n-1   +   [X]/2.
                                                     1左移n-1位     [X]补右移一位
             
即X<0时[X/2]为补码右移1位+1<<(n-1)。

           得证。

   例: [X1]=0.1101010  则[X1/2]=0.0110101

       [X2]=1.0100110 则[X2/2]=1.1010011

                                              
 ·补码的算术左移

  算术左移就是乘2运算,与算术右移损失精度不同算术左移可能产生溢出。

                            末位补0
    结论:  [X]补 <---------------------------------->[2X]补
                           各位左移1位

   
    证明:  [X]= 2+X, X=[X]-2.

          2X=2[X]-4  ,[2X]=4 + 2X= 4 + 2[X]-4 =2[X]补 
 
           
得证。

   例: [X1]=0.0110100 则[2X1]=0|0.1101000=0.1101000,未溢出。

       [X2]=1.0010110 则[2X2]=1|0.0101100=0.0101100,溢出,因为乘2后符号变反。
 

3.反码表示

   反码又称1的补码,下面分别给出定点小数和定点整数的反码定义。

   设机器字长为n位,定点小数的反码定义如下:

       [X]反  =   X             ,0<=X<1

               2-2-(n-1)+X      ,-1<X<=0    (MOD(2-2-(n-1)))

     式中X表示真值,[X]表示真值X的反码。

   设机器字长为n位,定点整数的反码定义如下:


       [X]反  =   X             ,0<=X<2
n-1

               2n-1+X         ,-2n-1<X<=0    (MOD(2n-1))


例:设机器字长n=8

[+35]=(00100011)2

[-35]=(28-1)+(-35)=(11111111)2-(00100011)2=(11011100)2

[+0.8125]=(0.1101000)2

[-0.8125]=(2-2-7)+(-0.8125)=(1.1111111)2-(0.1101000)2=(1.0010111)2

       
·反码有如下性质:

1.正数的反码与原码相同,负数的反码为该负数对应的原码符号位不变,数值位按位取反。因此,在反码表示中,最高位为符号位,0表示正,1表示负,这一点与原码相同。

2.反码中也有两种0的表示,由定义[+0]=00...0 ,[-0]=11...1,这使得反码与真值不能一一对应。

3.假设机器字长为n,则

    ·反码表示的定点小数,范围为 -(1-2-(n-1))~+(1-2-(n-1))

    ·反码表示的定点整数,范围为 -(2n-1-1)~+(2n-1-1)

4.负数的反码大于正数的反码,这一点与原码类似。

5.反码与原码的转换。

当X>=0时,由定义,真值X=原码=反码

                       符号位不变
当X<0时   [X]  <---------------------------->[X]
                      数值位按位取反

证明:    只证X<0部分

         [X] = 2n-1-X

         [X]=2n -1 + X =  2n-1     + 2n-1 -1 -(-X)
         和X的原码比较:        符号位不变     按  位  取  反


4.移码表示

   计算机中常用移码来表示浮点数的阶码,阶码为整数,因此我们只介绍定点整数的移码表示。若机器字长为n位,则移码的定义如下:

           [X]=2n-1 + X  ,    -2n-1<=X<2n-1

   上式中X为真值,[X]表示真值X的移码,2n-1是一个固定的偏移值。

   
移码的性质:

1.移码的符号位。

   当-2n-1<=X<0时,0<=[X]<2n-1,即符号位为0.

   当0<=X<2n-1时,2n-1<=[X]<2n,即符号位为1.

   因此,移码中用0表示负,用1表示正,这点与原码,补码,反码都不同。

2.移码中0的表示是唯一的。[0]=000...0

3.移码的表示范围为 -2n-1<=X<2n-1

4.[X]与X呈线性正比关系。

5.移码与补码的关系:

    假设机器字长为n位,由定点整数移码与补码的定义:

    [X]=  2n-1+X       , -2n-1<=X<2n-1

    [X]=  X        ,  0<=X<2n-1

           2n+X     , -2n-1<=X<0

    ·当X<0时,[X]=2n-1 + 2n-1+X =[X]+2n-1,即X<0时,将[X]的符号改为1即为[X],将[X]的符号改为0即为[X]移。

    ·当X>=0时,[X]= 2n-1 + X=2n-1+[X],即X<0时,将[X]的符号改为0即为[X],将[X]的符号改为1即为[X]移。

综合两方面,可得出结论,将即X<0时,将[X]的符号位取反即得[X],反之亦然。
                             
                                  符号位取反
                      [X]移  <-------------------->[X]


   
转载请注明出处http://www.cppblog.com/RyanWang/archive/2010/02/17/107955.html