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

原创 -128的二进制有原码 反码和补码

2013年06月30日 ⁄ 综合 ⁄ 共 5041字 ⁄ 字号 评论关闭

转自:

http://kb.cnblogs.com/a/1450313/

 

第一次修订 2009-5-6  14:11

---------------------
   1.模的概念(我只讲个例子,具体的可以查数学中的 "同余模")
       在日常生活中,有许多化减为加的例子。例如,时钟是逢12进位,12点也可看作0点。
        当将时针从10点调整到5点时有以下两种方法:
         1.将时针逆时针方向拨5格,相当于做减法: 10-5=5
         2.将时针顺时针方向拨7格,相当于做加法:10+(12-5)=12+5=5    (模为 12)

   2.模的运用(采用模得到补码)
       1.补码的得来:是为了让负数变成能够加的正数,so,负数的补码=模-负数的绝对值
                    比如:-1 补码:1111 1111(10000 0000 -1得来)
                    当一个数要减1的时候,可以直接加 1111 1111
       2.原码的得来:(负数的原码,直接把对应正数的最高位改为1)
          原码能够直观的表示一个负数(能直观的把真值显示出来,如 -1为1000 0001
                                        其中最高位表示符号位,不进行算术计算)
       3.总结:补码相加,到第9位才舍弃(模10000 0000)
               原码相加,到第8位舍弃(模1000 0000)
               反码相加,到第8位舍弃(模1000 0000)
       3.原码和补码之间转换:
             1.补码=原码减1,再取反(便于理解)
               或 补码= 反码+1(便于描述和推理)
             2.演示:补码=原码减1,再取反
               如-1的原码1000 0001-->1000 0000(减1后)-->1111 1111(取反后)补码
             3.演示:补码= 反码+1)
               如-1的原码  1000 0001-->1111 1110(反码)-->1111 1111(加1)补码    
       4.重点:(特别是在有进位的时候)
           原码和反码的最高位是符号位,不参加算术运算,模为1000 0000(比补码少一个0)
           而补码所有位都可以相加,模为10000 0000(最高位不是符号位,补码是通过模 减去 负数绝对值得到的)
       5.推断-128的原码和补码(用补码= 反码+1)
          1.关于原码1000 0000,表示的是-0,还是-128呢?(答案是-128而不是-0)
            1.先看看原码的概念吧:正数的符号位为0,负数的符号位为1,其它位按照一般的方法来表示数的绝对值
            2.0是负数吗?0既不是正数也不是负数,那么它的符号位到底是0还是1呢?(0的符号位为0,不能为1)
            3.看看负数补码的公式:负数的补码=10000 0000(模)-数的绝对值
                       比如:-1 1111 1111 =10000 0000-0000 0001
                             -2 1111 1110 =10000 0000-0000 0010
               现在假设-0为负数,那么
                -0的补码应该是10000 0000 - 0(这个0,姑且教0的绝对值吧)=0000 0000
                反码:1111 1111(0000 0000 -1=0000 0000 +1111 1111=1111 1111)
                原码:1000 0000
               现在来推-128
                -128的补码:10000 0000 - 1000 0000(+128没有符号位)=1000 0000
                      反码:1111 1111(1000 0000 -1=1000 0000+1111 1111=1111 1111)(补码-1)
                      原码:1000 0000(反码取反)
            从上面看来,一个原码对应了2个补码
            但是仔细分析:原码的概念,负数的符号位为1,但是0不是负数,所以不能用此公式
                          0也不是正数,但是可以把0定义为原码、反码和补码都一样(即0000 0000)
                          而且据说可以推断出0的补码只有一个(有兴趣的 可以去推一下,呵呵)
            现在原码1000 0000就唯一表示-128了,而不会表示出-0,因为-0不能用这个公式计算
            现在,补码1000 0000的原码是1000 0000(已证明),那么原码1000 0000的补码是1000 0000吗?
               原码 1000 0000  (-128,进位被舍去)
               反码 1111 1111
               补码 1000 0000(1111 1111(反码) + 1=1000 0000,这里实际上真正相加的是1111 1111后面的7位,
                        第1位是符号位始终不会变,所以,当进到第8位的时候,就表示溢出了,会被舍弃)
          2.综上所述:1.-128的补码和原码一样都是1000 0000,
                      2.0的原码、反码和补码都一样(即0000 0000)
                      3.如果把-0当做负数,1000 0000就会有歧义(事实上0的补码只有一个0000 0000)

 

第一次的手稿 2009-5-5 22:47

-----------------
   1.使用反码的意义:
      1.使符号位能与有效值部分一起参加运算,从而简化运算规则。从而可以简化运算器的结构,提高运算速度;
           (减法运算可以用加法运算表示出来。)
      2.加法运算比减法运算更易于实现。使减法运算转换为加法运算,进一步简化计算机中运算器的线路设计。
   2.负数的二进制数串表示一般用补码:(如何通过原码推补码,特别是-128的解释)
      1.先给出3个原则:
        1.因为使用补码可以将符号位和其他位统一处理,同时,减法也可以按加法来处理,即如果是补码表示的数,
         不管是加减法都直接用加法运算即可实现。
        2.两个用补码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃(模的概念,补码的模10000 0000)
         比如:1111 1111(-1) +1000 0001(-127)=1000 0000(-128,实际上最高位有3个1,进位一次后,还保留一个1)
              1111 1110(-2) + 0000 0100(4) = 0000 0010(2)
        3.模的规则:(自己的推断)
              1.补码的模为10000 0000
              2.反码的模为1000 0000(从反码的定义也能够知道,即反码的运算不涉及符号位)
              3.模的解释
                 在日常生活中,有许多化减为加的例子。例如,时钟是逢12进位,12点也可看作0点。
                 当将时针从10点调整到5点时有以下两种方法:
                  1.时针逆时针方向拨5格,相当于做减法: 10-5=5
                  2.时针顺时针方向拨7格,相当于做加法:10+(12-5)=12+5=5    (模为 12)
      2.原码、反码和补码的定义:(主要讨论负数的)
         1.正整数的原码、反码和补码都一样
         2.负数:
            1.原码就是原来的表示方法
            2.反码是 原码除符号位(最高位)外取反
            3.补码=反码+1
      3.举例:以一个单字节来说:(即8位)
       -1 原码 1000 0001(通过原码得到真值)
          反码 1111 1110
          补码 1111 1111(通过补码得到二进制)
       -2 原码 1000 0010
          反码 1111 1101
          补码 1111 1110
     **如此类推:原码 1000 0000  (-128)(重点)
                反码 1111 1111
                补码 1000 0000(1111 1111 + 1=1000 0000,这里实际上真正相加的是1111 1111后面的7位,
                        第1位是符号位始终不会变,所以,当进到第8位的时候,就表示溢出了,所以会被舍弃,
                        也就是说反码的模是1000 0000,而补码的模是:10000 0000比反码多一位)
       如果用补码反推原码
         补码1000 0000
         反码1111 1111(1000 0000 -1=1000 0000+1111 1111(相当于2个补码相加,可用模的规则)=1111 1111)
         原码1000 0000
      4.感慨:很多群人解释不通了,就武断的说-128的二进制为1000 0000,并断定它没有反码和原码,还说是"规定"
        而我怎么也没有找到官方的这么个规定(个人觉得这是不严谨的也是不负责任的,呵呵)

      5.具体的计算演示:
            1+(-1)=0
           0000 0001 + 1111 1111=0000 0000
           1+(-2)=-1
           0000 0001 + 1111 1110=1111 1111(-1)
           2+(-1)=1
           0000 0010 + 1111 1111=0000 0001
           (-128)+1=-127
           1000 0000 +0000 0001=1000 0001(补)
           1000 0001(补码)
           1000 0000(反码=补码-1)
           1111 1111(原码 =-127)
   3.有一个不正确的解释,貌似还写成书了(个人认为)
       采用补码表示还有另外一个原因,那就是为了防止0的机器数有两个编码。原码和反码表示的0
       有两种形式+0和-0,而我们知道,+0和-0是相同的。这样,8位的原码和反码表示的整数的范围就是-127~+127
       (11111111-01111111),而采用补码表示的时候,00000000是+0,即0;10000000不再是-0,而是-128,这样,
       补码表示的数的范围就是-128~+127了,不但增加了一个数得表示范围,而且还保证了0编码的唯一性。
    
    我的观点:包括写上面的话的人自己也说过,10000000(补码)没有反码和原码,既然这样,如何得出结论
    1000 0000曾经表示的是-0,其实通过上面的分析,1000 0000是有反码(1111 1111)和原码的(1000 0000)

   4.一些好的概念:
      由于计算机中符号和数字一样,都必须用二进制数串来表示,因此,正负号也必须用0、1来表示。
      用最高位0表示正、1表示负, 这种正负号数字化的机内表示形式就称为“机器数”,
      而相应的机器外部用正负号表示的数称为“真值”,将一个真值表示成二进制字串的机器数的过程就称为编码
   5.参考资料:http://www.cnblogs.com/ASPNET2008/archive/2009/04/29/1446471.html

抱歉!评论已关闭.