原码一位乘法器设计_对原码、反码和补码的加深理解

我们知道计算机语言可以简单概括为三类,分别是机器语言、汇编语言和高级语言。机器语言是由二进制组成的编码,由无数个0和1组成。在二进制系统中,每个0或1就是一个位,而位是数据存储的最小单位,可称之为比特(Bit)。在计算机高级语言(Java)中,整数类型变量中有字节型(byte),它与比特的换算关系为1byte=8bit,也就是1个字节等于8个比特。 8个比特在二进制编码中的表现形式(以数1为例)是这样的: 0000 0001 转换为十进制数就是2^0=1 而在一般情况下它能表示的最大范围数为 1111 1111 最小范围数为 0000 0000 最大范围数转换为十进制数也就是2^8-1=255,最小范围数为0,范围为0~255。而实际字节型(byte)的取值范围却为-2^7~2^7-1即-128~127,这是为什么呢? 现代数学中数字有大小和正负之分,可以进行算术运算(加减乘除),然而对于计算机来说,数字都是以无符号位的二进制数表示,它既分不清大小,也分不清正负。为了解决这个问题,就引入了原码、反码、补码这个概念。 我们先看原码的定义:
原码(true form)是一种计算机中对数字的二进制定点表示方法。原码表示法在数值前面增加了一位符号位(即最高位为符号位):正数该位为0,负数该位为1(0有两种表示:+0和-0),其余位表示数值的大小。——百度百科
计算机中所有的数均用0、1编码表示,数字的正负号也不例外,如果一个机器数字长是n位的话,约定最左边一位用作符号位,其余n-1位用于表示数值。——维基百科
对于字节型来说,符号位(从右向左最后一位)决定正负而不参与数值运算,在原码中,0000 0000代表十进制数0,1000 0000代表十进制数-0,而0000 0001代表十进制数1,1000 0001代表十进制数-1,我们可以观察到他们的异同: 相同之处: 对于±0和±1,最高位(符号位)都决定了它们的正负情况。 不同之处: 对于+0和-0来说,现实中运算并没有正负之分,也就是它们应该是相等的。一个字节共8位,其中7位表示数,一位代表符号,这样的结果就是0000 0000和1000 0000都可以表示为0。在最初是通过CPU执行两次比较来识别±0的,但是这种方式不仅增加了成本,也给电路的设计带来了挑战,最终经由补码来解决这个问题。 原码的优点在于简单直观的反映了一个数的大小正负情况,然而它却不能直接参与减法运算。 以1-1为例,计算机中减法运算可以理解为正数+负数,故1-1在计算机实际运算中等于1+(-1),也就是                                 0000 0001                             +                                 1000 0001                             =                                 1000 0010 十进制数为-2,可知原码直接参与负数运算是不被允许的 反码就是用来解决原码运算问题的过渡码: 反码的概念:
反码通常是用来由原码求补码或者由补码求原码的过渡码。根据定义,可以得到机器数的反码的整数和小数中“0”的表示形式各有2种,“+0”和“-0”不一样,以8位机器数为例,整数的“+0”原码为0,0000000,反码为0,0000000;整数的“-0”原码为1,0000000,反码为1,1111111;小数的“+0”原码为0.0000000,反码为0.0000000;小数的“-0”原码为1.0000000,小数的“-0”反码为1.1111111。反码跟原码是正数时,一样;负数时,反码就是原码符号位除外,其他位按位取反。[1]——百度百科
可知对于正数来说,反码=原码,对于负数来说,反码=符号位不变,其它位按位取反 我们看看反码在二进制的运算情况 以1-1为例 1的原码0000 0001
1的反码0000 0001 -1的原码1000 0001
-1的反码1111 1110 也就是                                 0000 0001                             +                                 1111 1110                             =                                 1111 1111 1111 1111转换为原码得1000 0000,十进制也就是-0 以1-2为例 1的原码0000 0001
1的反码0000 0001 -2的二进制; -2的原码1000 0010
-2的反码1111 1101 也就是                                 0000 0001                             +                                 1111 1101                             =                                 1111 1110 1111 1110转换为原码得1000 0001 ,十进制也就是-1 以2-1为例 2的原码0000 0010
2的反码0000 0010 -1的原码1000 0001
-1的反码1111 1110 也就是                                 0000 0010                             +                                 1111 1110                             =                               1 0000 0000 实际位数为8,这里有9位,所以最高位1溢出被自动舍弃,即为0000 0000,原码0000 0000,十进制为0 以-1-1为例 -1的原码1000 0001
-1的反码1111 1110 也就是                                 1111 1110                             +                                 1111 1110                             =                               1 1111 1100 实际位数为8,这里有9位,所以最高位1溢出被自动舍弃,即为1111 1100,原码为1000 0011十进制为-3,同理-1-2结果为-4 由上面的例子可以发现些许问题,反码计算中,某些情况下(如2-1)实际正确值=实际结果值-1,如果结果为±0,那么+0和-0的区分也存在问题,如果正数+负数<0结果正确,反码无疑也是行不通的,由此便引入了补码的概念(注意:补码的运算中最高位是参与运算的,相当于无符号位运算)。
在介绍补码概念之前,先介绍一下“模”的概念:“模”是指一个计量系统的计数范围,如过去计量粮食用的斗、时钟等。计算机也可以看成一个计量机器,因为计算机的字长是定长的,即存储和处理的位数是有限的,因此它也有一个计量范围,即都存在一个“模”。如:时钟的计量范围是0~11,模=12。表示n位的计算机计量范围是0-2^n-1,模=2^n.“模”实质上是计量器产生“溢出”的量,它的值在计量器上表示不出来,计量器上只能表示出模的余数。任何有模的计量器,均可化减法为加法运算 [3]  。假设当前时针指向8点,而准确时间是6点,调整时间可有以下两种拨法:一种是倒拨2小时,即8-2=6;另一种是顺拨10小时,8+10=12+6=6,即8-2=8+10=8+(12-2)(mod 12).在12为模的系统里,加10和减2效果是一样的,因此凡是减2运算,都可以用加10来代替。若用一般公式可表示为:a-b=a-b+mod=a+(mod-b)。对“模”而言,2和10互为补数。实际上,以12为模的系统中,11和1,8和4,9和3,7和5,6和6都有这个特性,共同的特点是两者相加等于模。对于计算机,其概念和方法完全一样。n位计算机,设n=8,所能表示的最大数是11111111,若再加1成100000000(9位),但因只有8位,最高位1自然丢失。又回到了 00000000,所以8位二进制系统的模为2^8。在这样的系统中减法问题也可以化成加法问题,只需把减数用相应的补数表示就可以了。把补数用到计算机对数的处理上,就是补码 [3]  。——摘自百度百科
概念中巧妙的用到了时钟来举例,假设当前时间为8点,要调到6点,有两种办法:一种是往回调拨2小时(逆时针),即8-2=6;另一种是往后顺拨10小时(顺时针),即8+10=6。这里用到了同余的概念,而不是简单地相加减。我们知道时钟从1到12类似首尾相连,衔接成一个圆,12点过后会回转到1点,而不会向上叠加为13、14等,12就是时钟的模。我们发现期望结果=8-2=8+(模=12-2)=8+10。 这里也可以以东南西北方位为例,假设指针所指为北边,要转到为西边,可以逆时针转90°,也可以顺时针转270°(360°-90°),360°就是方位的模。 西    ↑    东 8位的计算机每位的变化量为2,要么为0要么为1,所以总共能表示的数据有2^8=256个,无符号值的范围为0000 0000~1111 1111,也就是0~2^8-1即0~255,256即为字节型的模(这点有疑惑的可参照数组的特点,相当于索引从0~255,但实际长度为索引最大值255+1)。 如果数值大于255如1 0000 0000(十进制为2^8=256)则最高位1丢失,最终变成0000 0000,相当于时钟走过12点又回到1点。故计算机8位的模256=1111 1111+0000 0001(数1)=最高位数值+1。 推导过程: 这里的运算相当于无符号运算
以8-2为例,同理,8-2=8+(-2)=8+(计算机8位的模-2)计算机8位的模-2=1111 1111+0000 0001(数1)-0000 0010(数2)              =1111 1111-0000 0010(数2)+0000 0001(数1)              而1111 1111- 0000 0010(数2)=1111 1101=数(-2)的反码0000 0001(数1)+1111 1101=1+数(-2)的反码=数(-2)的补码故计算机8位的模-2=数(-2)的补码所以8-2=8+(计算机8位的模-2)=8+数(-2)的补码
8的二进制: 原码0000 1000
反码0000 1000 补码0000 1000 -2的二进制: 原码1000 0010
反码1111 1101 补码1111 1110 故8-2=8+(-2)=                                 0000 1000                             +                                 1111 1110                             =                             1  0000 0110 实际位数为8,这里有9位,所以最高位1溢出被自动舍弃,即为0000 0110,化为十进制数为2^2+2^1=6 由上面的推导公式可以发现规律: 计算机8位的模=最高位(1111 1111)+1 a-b=a+(计算机8位的模-b) 计算机8位的模-b=最高位-b+1 最高位-b=-b的反码 -b的反码+1=-b的补码 a-b=a+(-b)的补码 可知对于正数来说,补码=反码=原码;对于负数来说,反码=原码符号位不变,其它位按位取反,补码=反码+1 以以下几个例子来做测试: 1-2=1+(-2) 1的二进制: 原码0000 0001
反码0000 0001 补码0000 0001 -2的二进制: 原码1000 0010
反码1111 1101 补码1111 1110 故1-2=1+(-2)=                                 0000 0001                             +                                 1111 1110                             =                                 1111 1111 减1,转换为反码1111 1110,转换为原码1000 0001,十进制为-1 2-1=2+(-1) 2的二进制: 原码0000 0010
反码0000 0010 补码0000 0010 -1的二进制: 原码1000 0001 反码1111 1110 补码1111 1111 故2-1=2+(-1)=                                 0000 0010                             +                                 1111 1111                             =                              1 0000 0001 实际位数为8,这里有9位,所以最高位1溢出被自动舍弃,0000 0001由符号位可知为正数,其原码、反码、补码相等,将0000 0001转换为十进制数为1*2^0=1 1-1=1+(-1) 1的二进制: 原码0000 0001
反码0000 0001 补码0000 0001 正数的原码、反码、补码是一致的 -1的二进制: 原码1000 0001 反码1111 1110 补码1111 1111 负数的反码为原码符号位不变,其它位取反 负数的补码为反码+1 故1-1=1+(-1)=                                 0000 0001                             +                                 1111 1111                             =                              1 0000 0000 实际位数为8,这里有9位,所以最高位1溢出被自动舍弃,0000 0000的原码、反码、补码都是0 解答: 可知1个字节占8位,能表示的数据有2^8=256个。 二进制数范围为0000 0000~1111 1111即0~255,把它当作无符号数划分开来,可区分为0000 0000~0111 1111(0~127)和1000 0000~1111 1111(128~255),分别对应正负数。正数分到的区间为0000 0000~0111 1111,负数分到的区间为1000 0000~1111 1111。 已知补码相当于无符号数,对正数而言,原码=反码=补码,故字节型正数原码范围0000 0000~0111 1111一一对应0000 0000~0111 1111(0~127),即原码1(0000 0001)对应补码0000 0001(无符号数值1),原码127(0111 1111)对应补码0111 1111(127),共有128个数据;对负数而言,补码=原码取反+1,以原码-1为例,原码-1(1000 0001)对应的补码为1111 1111(无符号数值255),原码-2(1000 0001)对应的补码为1111 1110(无符号数值254)……原码-127(1111 1111)对应的补码为1000 0001(无符号数值129),剩下最后一个,原码-0(1000 0000)对应的补码为1000 0000(无符号数值128),可知0~255区间每个数都是独立不重复的,如果按照实际取值,-0对应无符号数值128,而规定的0的二进制数为0000 0000对应补码0000 0000(无符号数值0),“一山不容二虎”,为了保持独立性,规避±0区分问题,计算机中直接硬性规定1000 0000原码的实际值为-128,对应的补码为1000 0000(无符号数值128),所以负数的取值范围为-128~-1,有128个数据。 所以字节型(byte)的取值范围为(-128~-1)∪(0~127)为-2^7~2^7-1即-128~127。 补充: 2^0+2^1+……2^n=(2^n)-1 2进制数转换为10进制数 如0111 1111=2^6+2^5+2^4+2^3+2^2+2^1+2^0=2^7-1=127 除原码、反码、补码外还有移码
移码(又叫增码)是符号位取反的补码,一般用指数的移码减去1来做浮点数的阶码,引入的目的是为了保证浮点数的机器零为全0。——百度百科
若0111 1111为补码,则移码为1111 1111 以下是给我以启迪的链接,在此表示特别感谢
https://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.htmlhttps://blog.csdn.net/wenxinwukui234/article/details/42119265https://blog.csdn.net/u011080472/article/details/51280919https://blog.csdn.net/wn084/article/details/79963979https://blog.csdn.net/sixu_9days/article/details/79227131https://blog.csdn.net/big_big_white/article/details/79444651
aba9db79a9333fa09230505332d8a310.png
相关资源:模拟一位原码乘法
表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页