zoukankan      html  css  js  c++  java
  • 原创 128的二进制有原码 反码和补码

    转自:

    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

  • 相关阅读:
    Spring攻略学习笔记(3.00)AOP核心概念和术语
    zoj 3494
    第43周星期五
    findBugs学习小结
    第42周星期日
    Cookie知识小结
    第42周星期三
    第42周星期六
    第43周星期四小结
    第43周星期二
  • 原文地址:https://www.cnblogs.com/bayonetxxx/p/2043476.html
Copyright © 2011-2022 走看看