首页 > 其他分享 >原码、反码、补码

原码、反码、补码

时间:2022-10-24 14:44:07浏览次数:44  
标签:10 反码 二进制 补码 加减法 原码

补码诞生的背景

不论是在生活中还是虚拟网络中,人们总是习惯与10进制数字打交道,很容易理解10进制的加减乘除运算,但是我们知道计算机无法直接理解10进制,只能识别高低电平,一般人为设定0为低电平,1为高电平,所以又称计算机是二进制的。在计算机发展早期,人们要想使用计算机,只能使用计算机看懂的二进制与计算机打交道,如穿孔纸带,人们使用穿孔纸带将程序和数据转换为二进制码,带孔为1,无孔为0,计算机读取并处理完成后,同样在纸带上以二进制打孔输出计算结果,一般人很难操作这种早期计算机,只能是专业人士才能处理二进制的转换。随着科技的进步,普通人也能熟练的操作计算机,表面上似乎计算机已经理解了10进制,但是实际上,计算机最底层还是二进制的,这就需要10进制到二进制的自动转换以及使用二进制进行各种运算。

10进制到二进制的转换需要考虑两方面,第一个是编码格式,二进制中只有0和1,不同于常用的10进制使用 + 或者 - 符号代表正负数,要想让二进制只使用1和0代表正负数,需要找到合适的编码格式;第二个是运算,以加减运算为例,计算机内部是比较复杂的,计算机实现加法运算是很容易的,若直接作减法则比较复杂,需要处理借位等等,内部逻辑组件会增多,所以计算机一般在减去一个数的时候会转成加上这个被减数的负数,将减法转换成了加法,即A - B = A + (-B)。所以需要找到一种满足这两个方面的编码,目前10进制转换成二进制主要有三种方式:原码、反码、补码,下面将从编码格式和运算两方面对比这三种编码格式。

原码、反码、补码

原码

原码是最简单也是最直观的从10进制到二进制的编码格式,人为规定原码的最高位为符号位,正数为0,负数为1,其余所有位为10进制数的绝对值。如下面例子:

10进制 二进制原码(4位)
4 0 100(首位为0,代表为正数)
2 0 010(首位为0,代表为正数)
0 0 000(首位为0,代表为正数)
-2 1 010(首位为1,代表为负数)
-4 1 100(首位为1,代表为负数)

十进制和二进制原码转换

原码的优点是编码格式对人很友好,类似十进制中的正负号,原码用最高位0和1分别代码正负数,很直观的表示了正负数。但是原码也有一个很大的缺点,就是无法将减法转换成加法运算,如:

4 - 2 (10进制)= 4 + (-2)= 0 100 + 1 010 (二进制原码) = 1110 (二进制原码)= -6 (10进制)

上面例子计算4-2,将4-2转换成4+(-2)并用原码计算,得出的结果错误,原码虽然很直观转换了10进制数,但是计算输出的原码值并不正确,所以计算机不能直接使用原码存储和计算。

反码

反码的出现,主要是为了解决原码无法执行减法运算的问题,人为规定反码最高位为符号位,正数为0,负数为1,反码正数与原码正数格式一致,反码负数为负数绝对值的原码按位分别取反,如下面例子:

10进制 二进制原码(4位) 二进制反码(4位)
4 0 100(首位为0,代表为正数) 0 100(首位为0,代表为正数)
2 0 010(首位为0,代表为正数) 0 010(首位为0,代表为正数)
0 0 000(首位为0,代表为正数) 0 000(首位为0,代表为正数)
-2 1 010(首位为1,代表为负数) 1 101(首位为1,代表为负数)
-4 1 100(首位为1,代表为负数) 1 011(首位为1,代表为负数)

十进制和二进制反码转换

反码的负数编码格式不像原码那样直观,但是却可以将减法转换成加法了,反码减法规则为:A - B = A + (-B),如果最高位发生了溢位,则需要在最低位加上1,如下面两个例子:

1)4 - 2 (10进制)= 4 + (-2)= 0 100 + 1 101 (二进制反码) = 1 0001 (二进制反码,发生了溢位)= 0001 + 0001(最低位加1) = 0010 (二进制反码)= 2(10进制)

2)2 - 2 (10进制)= 2 + (-2)= 0 010 + 1 101 (二进制反码) = 1111 (二进制反码)= - 0 (10进制)

运用反码减法规则,得到的上面两个例子的减法结果是正确的,所以计算机是可以使用反码存储和计算的,早期的计算机如CDC 6000、LINC、PDP-1等都是使用反码的,但是反码也有两个缺点:

1)0有两种编码,+0 (0000)和 -0 (1111),在判断0时,需要分别判断0000和1111;

2)反码减法的算法规则比较复杂,需要增加计算机内部逻辑组件额外判断溢位,会影响计算效率。

补码

补码是现代计算机使用的编码格式,解决了上面反码的两个缺点。正数的补码与原码格式相同,负数的补码是将负数绝对值的原码分别按位取反,并加1,如下面例子:

10进制 二进制原码(4位) 二进制补码(4位)
4 0 100(首位为0,代表为正数) 0 100
2 0 010(首位为0,代表为正数) 0 010
0 0 000(首位为0,代表为正数) 0 000
-2 1 010(首位为1,代表为负数) 1 110
-4 1 100(首位为1,代表为负数) 1 100

十进制和二进制补码转换

补码的减法规则比较简单,按照最简单的转换公式A-B = A + (-B),当减去一个数时直接转换成加上被减数的负数即可,不用像反码那样额外处理溢位,如下面两个例子:

1)4 - 2 (10进制)= 4 + (-2)= 0 100 + 1 110 (二进制补码) = 1 0010 (二进制补码,发生了溢位,直接丢弃溢位)= 0010(二进制补码) = 2(10进制)

2)2 - 2 (10进制)= 2 + (-2)= 0 010 + 1 110 (二进制补码) = 1 0000(二进制补码,发生了溢位,直接丢弃溢位)= 0000 (二进制补码) = 0(10进制)

使用了补码的加法,上面两个例子得出的结果都是正确的,相对于反码,补码加法更简单,直接丢弃溢位,不需要针对溢位单独处理,所以用补码做运算效率高。虽然补码运算过程很简单,但是转换和运算规则却很难理解,要弄明白其中的原理,就需要揭开补码背后的数学奥秘。

加减法

普通算术加减法

普通算术加减法是我们在生活中一直使用的,也是最简单和最容易理解的,通常人为使用 + 和 - 符号规定正负数,正数通常省略 + 符号, 如果10,20,-10,-20,正负数的加减运算则可以看成是一维运算,如下图:
image
上图是普通算术加减法示意图,当执行加法运算时,需要向右移动,比如0+3,在0位置向右移动3位,即为0+3的结果;同样的,当执行减法运算,向左移动。向左和向右是没有尽头的,可以一直移动到正的无穷大或者负的无穷大。普通算术加减法简单直观,很容易被人理解,但是对于计算机要实现这样的算术加减法,既要区分正负数,又要分别实现加减法,设计就会很复杂,效率会很低,所以这套算术加减法并不适用计算机。所以需要找到一种不需要区分正负数就可以实现加减法转换的规则,那么计算机运行效率就会最高。

模N加减法

模N加减法正是不需要区分正负数就可以实现加减法转换的运算方式,不同于普通算术加减法,它是二维运算,要理解模N加减法比较困难,可以先用生活最典型的时钟举例,如下图:

image

上面是生活中常见的时钟,如果当前时间为凌晨1点,要知道5个小时之后的时间是多少,只需要顺时针旋转5格,指向了6点,即为1+5的结果;如果想知道5个小时之前的时间是多少,需要逆时针旋转5格,指向晚上8点,即为1-5的结果。时钟顺时针相当于时间向前走,逆时针相当于时间往后走,但是时钟不会指向无穷大的数,当转过24个小时(24小时制)又回到了原点。在时钟转动中,1-5的最终结果为晚上8点,逆时针旋转5个小时就可以得到正确结果,同时也可以顺时钟旋转19个小时(24-5,24小时制),两种方式旋转都最终指向了晚上8点。所以任意逆时针旋转得到的结果都能通过顺时钟旋转得到,当逆时针旋转N个小时,与顺时针旋转24-N小时相等,24又称为模,如果把顺时针看成是加法,逆时针看成是减法,那么时钟旋转可以看成模24的加减法运算,满足公式A-m=A+(24-m),即在时钟任一时刻A点,从A点逆时针旋转m个小时得到的结果,与从A点顺时针旋转24-m得到的结果一致。模N运算将减法转换成了加法。

计算机使用的二进制位数是有限制的,比如4位,8位,16位,64位等等,当数值太大超过最大位数时,会发生溢出,重新归0,所以计算机的二进制能表示的数不是无穷大的,由于溢出归零的特点,更像时钟旋转,如下图:

上图的四位二进制表示了从0000-1111,当超出1111时,四位已无法表示,会发生溢出,高于四位的位会被丢掉,比如1111加上2等于10001,10001包含五位二进制,最高位1会被丢掉,实际结果为0001,与时钟运算很相似,相当于在1111顺时针旋转了2个数。在时钟运算中,将顺时针看成加法,逆时针看成减法,那么时钟运算可以看成是模24的加减法,同理四位二进制也可以看成是模N的加减法,在4位二进制中,转一圈为2^4=16,所以4位二进制的加减法为模16的加减法,减法很容易的就被转换成了加法,即满足模N加减法公式:A-m=A+(16-m)。

虽然根据模N加减法实现了加减法转换,但此时又有新的问题,4位二进制只有1和0,是没有区分正负数的,而人们在计算的时候是要区分正负数的,所以需要人为将部分二进制划分为负数,另一部分划分为正数,根据模N加减法公式A-m=A+(16-m),当A为零点时,根据模N加减法公式得到 0-m=0+16-m,即-m=16-m,即将零点A逆时针移动m得到负数m,同时这个负数m也可以从零点A顺时针移动16-m得到,零点A可以为上面四位二进制任意一位,比如定义0000或者0001为零点都是可以的,但是为了简单运算,人为规定0000为零点,0000逆时针方向的为负数,顺时针方向的为正数。如在0000逆时针旋转1个数或者顺时针旋转16-1得到1111,那么1111代表-1,相应的顺时针移动一个数为+1,即用0001表示+1;同理在0000逆时针旋转2个数或者顺时针旋转16-2得到1110,那么1110代表-2,相应的顺时针移动两个数为+2,即用0010表示+2;同理1101和0011分别为-3和+3,1100和0100分别为-4和+4,1011和0101分别为-5和+5,1010和0110分别为-6和+6,1001和0111分别为-7和+7,但是1000比较特殊,0000逆时针旋转8个数得到1000,所以1000为-8,相应的顺时针旋转8个数也得到了1000,1000既能表示-8又能表示+8,为了不产生冲突,人为规定1000为-8。如下图:

image

上图中的四位二进制根据模N加减法划分出了正负数,同理对任意n位二进制,模N等于=2^n,根据上面的模N加减法公式得到-m = N - m = 2^n - m = (2^n -1) - m + 1,最终得到了负数推导公式-m = (2^n -1) - m + 1,(2^n-1)-m即为负数的原码绝对值按位取反,之后再加上1可以快速得到负数编码,又称这种负数编码为补码。补码负数范围转换成10进制为 -1 ~ -2^(n-1),正数范围转换成10进制为 0 ~ 2^(n-1)-1,所以补码转换成10进制为 -2^(n-1) ~ 2^(n-1)-1。

总结

要想弄清楚补码,必须要弄清楚补码要解决的问题,计算机是二进制的,无法直接表示正负数,另外在计算机内部直接实现减法,也会影响计算机效率,所以人们希望要找到一种既能使用二进制表示10进制正负数的编码格式,同时这种编码格式又能满足将减法转换成加法进行运算,同时满足这两个条件有反码和补码,但由于反码中的0有两个编码格式,另外反码加法运算也比较复杂,慢慢地反码被淘汰了。补码刚好解决了反码的两个缺点,所以补码成了现代计算机的通用编码。

补码加减法运算不同于常规的算术加减法,补码使用了模N加减法,要想完全理解补码,首先要理解模N加减法。

标签:10,反码,二进制,补码,加减法,原码
From: https://www.cnblogs.com/qq53462202/p/16821375.html

相关文章

  • 原码、反码、补码
     在计算机运算的时候,都是以补码的形式运算的正数的原码、反码、补码都一样负数的反码=它的原码符号位不变,其余位取反负数的补码=负数的反码+10的反码、补码都是0......
  • Java原码补码反码
    对于一个8位原码,01101010和11000110,求它们的补码。已知补码01101010和11000110,求它们的原码。(要求如题4)注:进制和原码等概念属于计算机编程基础知识,建议了解并熟悉它。答:(1)......
  • 关于负数补码为什么原码是按位取反再+1
     8位下,求123和-123的补码。8位补码表示的值为-128-127。[-123]补码=[-01111011]补码=2^8+(-01111011)......
  • 123按位取反是多少?原码、反码、补码及其运算
    如题,在整数运算中总是不清楚某个数的取反和反码到底有什么区别,遂写下此博客,有参考的地方在文末中会贴出出处。在阅读本文章之后会对你了解计算机中一些基础有所帮助,文章包......
  • 负数补码(16进制转10进制的负数)
    假如我想通过modbustcp接收设备上传的报文,该设备显示为负数,但报文上无法解析出来(温度报文异常,负数无法显示与转换)。这时候,我就需要对这个报文进行负数补码形式,16进制转10......
  • 源码、反码、补码和精度损失
    数据类型转换,转换过程中可能导致溢出或损失精度1.源码:源码就是二进制的数字并且开头的一位代表符号位。例:(+1)的源码:00000001(-1)的源码:100000012.反码:正数......
  • 原码、反码、补码
    对于有符号的而言:1、二进制的最高位是符号位:0表示正数,1表示负数2、正数的原码、反码、补码都一样(三码合一)3、负数的反码=它的原码符号位不变,其他位取反4、负数的补码......
  • 什么是补码
    什么是补码众所周知,符号位不变,负数原码数值取反后\(+1\)即可得到补码,补码可以用加法来代替减法,刚学的小朋友可能完全不知所然,补码是个完全模糊的概念。我们先用十进制来......
  • 位运算符:原码、反码、补码
    位移(涉及到二进制中的原码,反码,补码)⭐必记↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓:对于有符号的数而言,有以下几点1.二进制的最高位是符号位:0表示正数,1表示负数(区别......
  • js取补码并转换为2进制
    (-1>>>0).toString(2)//返回结果'11111111111111111111111111111111'(4>>>0).toString(2)//返回结果 '11111111111111111111111111111100'如何计算一个32位2进制......