现在的位置: 首页 > 综合 > 正文

java基础备忘(原码、反码、补码)

2013年11月16日 ⁄ 综合 ⁄ 共 4225字 ⁄ 字号 评论关闭

注意点:1、负整数在计算机中是以补码存储的。 2、绝对值相同的两个数原码相同

关于补码,原码,反码的问题,说简单,很简单,基本人人都会算,会求解。 可是没几个人能对这几个概念的来龙去脉搞得清清楚楚,明明白白的. 比如,为什么引入编码,为什么引入原码,又为什么引入反码. 反码存在的意义是什么,补码的引入原因,为什么补码能够把符号位一起运算?补码的优势到底在哪里?根据韩大师的指示(韩宏博士),我们应该对问题多多思考,多想几个为什么. 如果你搞不懂来龙去脉,恐怕后面的操作几乎可以把你搞得晕头转象,好象懂了,会做题了.可是心理总觉得没吃透,对吧??

       下面我把我的思考分享给大家:

       计算机的基本功能是对信息进行处理.所以我们引出了一个重要的概念 信息表示的数字化,包括信息的表示 ,信息的存储,信息的转化,信息的加工,信息的传送,和对这些过程的控制.

       首先,我们把重点放在信息的表示,计算机中进位记数制,我想应该都明白为什么用二进制吧? 然后我们就需要对它进行编码? 为什么要进行编码呢,在人脑中只是约定了+为正数,-为负数,就可以在人脑中进行高度抽象的运算了,但是,在计算机中不行啊,计算机很傻的,计算机中的任何行为都依赖于它的物理结构,它没有思维的. 所以你必须告诉它什么是正,什么是负!所以我们必须进行编码,以区分正负.

原码的出现与衰落

        最开始的时候,人们约定在数前面第一位用做表示符号的位, 1表示负 0 表示正. 他们称之为原码. 很不错,可以成功的区分出正负了. 可是马上就意识到它的一些局限性了.

       1加减的不方便, 符号位需要单独处理,单独判断.同0相加或相减,那好判断. 可异号呢? 那就涉及一个判断是否够减的逻辑了.很难做到.

        2 +0 表示为 0000
-0 表示为 1000 ,这就存在二义性了,计算机中是绝对不能容惹二义性的东西存在的.

补码的大放光彩

    原码的缺点使人们要找出一种新的编码,这种编码就是补码.首先它必须继承原码的特点(可以表示正负)而且它至少应该有两个优点,可以把符号位一起运算和0没有二义性.怎么才能做到呢? 如果是你,你能创造出这种编码吗?

    在日常生活中,我们发现时钟有这样一个特点,就是以12为模,13点是多久呢?舍弃模12 大家都知道就是1点了. -1 点也就是11点. 两者是完全等价的,因为它们有模12.通过这个特点可以做什么? 大家注意了,可以变减为加啊,比如:-1点再过5个小时是几点, -1+5=4点,我们可以这样变换(-1+12)+5=4 ,你会发现这个等式是不是错了?应该是16对啊,你错了,满12就已经溢出了,只剩下4.

    而计算机是否也有这个特点呢?答案是肯定的,实现模运算的基础显然就是寄存器的长度是固定的.那么变减为加那就算是实现了.例如82-54=82+46=(1)28 ,那么到底是怎么样才能把符号位一起运算呢?我们知道正数的补码就是本身,负数的补码就变反加一. 我们来举个例子 比如异号想加 A-B=87-25,我们把它转换成补码=0(87)+1(75)=062,嘿嘿,发现没有 符号位一起运算了.结果为62,再来,把它反过来 25-87 ,转换成补码0(25)+1(13)=1(38),这里有的同会说,不对了,结果不应该是-38.
你再仔细看看,我提示下补码+补码=? ,也是等于补码啊,1(38)的真值是-62,对吧? 完全可以把符号一起运算.

     最关键的部分就在这里了,把符号位一起运算的理论依据是什么,什么样的编码可以连同符号位一起运算,而原码为什么不能把符号位一起运算? 经过我一天一夜的思考 :),大家看看这样理解对不对. 数 A,有正有负,对吧? 也就是A+(-A)=0 ,哈哈,就是它了,我们设A=0001,你看原码,A=00001,-A=10001,A+(-A)=10010,哈哈1+(-1),变成-2了,再看补码 00001+11111=00000,哈哈,完全正确,你如果再要去想为什么,也很简单了一个数加去它的补数=什么?
当然=模了,模的定义就是模减去一个数的结果就是这个数的补数. 等于模了,舍去模,那不就变成0 了. 这就是连同符号位一起运算的依据.

       你还会发现一个特点,这个特点在我们物理上的具体实现时是相当重要的.请看原码 0001=0000000001,而1001是否等于111111111001呢,很明显是不可能的. 而补码1001绝对是等于1111111001的,不信你算算看,这个性质就叫符号的可扩充性.

       

反码的出现原因

       哈哈,补码很明显是我们的最佳选择了,为什么又弄一个叫反码的东西来,我看到这里的时候也是很不理解,还是韩大师那句话,要多思考.它是怎么回事呢?它的 思路应该是反过来的,我们联系联系具体的逻辑元器件,是不是有个非门的东西啊?你是1它变成0 ,0变成1,说白了就是按位取反啊,所以反码是从下层映射上来的东西,我们为什么要研究它,就是因为它的物理太容易实现了,我们不得不研究它的性质,研究它与我们的补码的关系. 结果,果不起然,关系密切着呢, 是什么啊,反码加1就变补码了.

这就是三大编码了,原码,反码,补码.

 

1.原码
  正数的符号位为0,负数的符号位为1,其它位按照一般的方法来表示数的绝对值。用这样的表示方法得到的就是数的原码。
  【例1】当机器字长为8位二进制数时:
            X=+1011011                  [X]原码=01011011
            Y=+1011011                [Y]原码=11011011
            [+1]原码=00000001             [-1]原码=10000001
            [+127]原码=01111111           [-127]原码=11111111
  原码表示的整数范围是:
  -(2n-1-1)~+(2n-1-1),其中n为机器字长。
  则:8位二进制原码表示的整数范围是-127~+127
             16位二进制原码表示的整数范围是-32767~+32767

2.反码       

    对于一个带符号的数来说,正数的反码与其原码相同,负数的反码为其原码除符号位以外的各位按位取反。【例2.14】当机器字长为8位二进制数时:
  X=+1011011 [X]原码=01011011   [X]反码=01011011
  Y=-1011011 [Y]原码=11011011   [Y]反码=10100100
  [+1]反码=00000001   [-1]反码=11111110
  [+127]反码=01111111   [-127]反码=10000000
  负数的反码与负数的原码有很大的区别,反码通常用作求补码过程中的中间形式。        反码表示的整数范围与原码相同。

3.补码
    正数的补码与其原码相同,负数的补码为其反码在最低位加1。

【例2】(1)X=+1011011 (2) Y=-1011011
  (1)根据定义有: [X]原码=01011011        [X]补码=01011011
  (2) 根据定义有: [Y]原码=11011011        [Y]反码=10100100  
  [Y]补码=10100101
  补码表示的整数范围是-2n-1~+(2n-1-1),其中n为机器字长。
  则:8位二进制补码表示的整数范围是-128~+127
        16位二进制补码表示的整数范围是-32768~+32767
  当运算结果超出这个范围时,就不能正确表示数了,此时称为溢出。

所以补码的设计目的是:

  使符号位能与有效值部分一起参加运算,从而简化运算规则.

  使减法运算转换为加法运算,进一步简化计算机中运算器的线路设计

 

4.补码与真值之间的转换

    正数补码的真值等于补码的本身;负数补码转换为其真值时,将负数补码按位求反,末位加1,即可得到该负数补码对应的真值的绝对值。

  【例3】[X]补码=01011001B,[X]补码=11011001B,分别求其真值X。
  (1)[X]补码代表的数是正数,其真值:
                                             X=+1011001B
                                                =+(1×26+1×24+1×23+1×20)
                                               =+(64+16+8+1)
                                               =+(89)D
  (2)[X]补码代表的数是负数,则真值:
                                             X=-([1011001]求反+1)B
                                               =-(0100110+1)B
                                               =-(0100111)B
                                               =-(1×25+1×22+1×21+1×20)
                                               =-(32+4+2+1)
                                               =-(39)D

5.   原码、反码及补码的算术运算
       因为这三种数码表示法的形成规则不同,所以算术运算方法也不相同。

      原码:与我们的日常中算术运算相同。
      反码:先转换为反码形式,再进行加减运算。它的减法可以按A反+[-B]反的形式进行.
      补码:先转换为补码形式,再进行加减运算,其减法可以按A补+[-B]补进行.

6.   溢出及补码运算中溢出的判断
       溢出可以描述为运算结果大于数字设备的表示范围。这种现象应当作故障处理。
       判断溢出是根据最高位的进位来判断的

 

抱歉!评论已关闭.