计算机为什么采用补码来进行运算

基础知识了解:

在计算机内,整数的长度是确定的,在字长为32位的计算机中,整数的长度就是32个二进制,这其中还包括了符号位(1表示正,0表示负)。这里面我们为了方便描述,就假设机器字长为8位。

例如,十进制整数23,二进制真值表示为10111,其原码表示为 0001 0111。

十进制整数-23,二进制真值表示为-10111,原码表示为 1001 0111。

简而言之,源码就是最高位为符号位,其他位表示该数的绝对值

如果计算机内部采用原码表示数,那么在进行加法和减法运算的时候,最终都转化为两个绝对值的加运算和减运算,因此,在设计计算器的时候就既需要设计加法运算器,又要设计减法运算器(代价有点大,是否可以就用一种类型的运算器呢? 其实大多数人都喜欢做加法运算,不太喜欢用减法运算)。

补码的思想

我们希望只设计加法运算器,不用减法运算器,我们希望找到一种方案,采用这种方案做加运算 1 + ( -1 ) ,两个数可以直接根据二进制的加法规则做运算,得到0,而不必做减法。
用 0000 0000表示0是很自然的想法,用 0000 0001到 0111 1111表示1到127的正数,也是自然的想法,此时,最高位的0可以做符号标识,也可以看成普通的二进制位。
现在问题是:怎么表示-1呢?
我们做一次逆向思维,0000 0001加上什么样的二进制数可以得到0000 0000?即:从右向左思考,加数的最右边的最低位必须是1,根据二进制加法规则:1+1=0,进位为1。再考虑次低位,加数的次低位也必须是1,然后加上1得0进一位,...依次类推,加数的8为都必须是1,才可以得到8个0。问题是最后产生一个进位,即:0000 0001 + (1111 1111)= 1 0000 0000
这在数学上是不可接受的,但是在计算机中去刚好合适,因为在设计中,每个数的长度是确定的,所以无论结果最后是多少,都只保留8位,多余的位会被丢弃。因此,我们可以将 1111 1111来表示-1,下面就是采用一种方式来合理的将-1怎么变成 1111 1111这种形式。

补码的定义:

带符号整数有原码、反码、补码等几种编码方式。原码即直接将真值转换為其相应的二进制形式,而反码和补码是对原码进行某种转换编码方式。正整数的原码、反码和补码都一样,负数的反码是对原码的除符号位外的其他位进行取反后的结果(取反即如果该位為0则变為1而该位為1则变為0操作)而补码是先求原码的反码,然后在反码的末尾位加1后得到结果,即补码是反码+1
补码就是最方便的方式。它的便利体现在,所有的加法运算可以使用同一种电路完成。
以-8作为例子。假定有两种表示方法。一种是直觉表示法,即10001000;另一种是2的补码表示法,即11111000。请问哪一种表示法在加法运算中更方便?
随便写一个计算式,16 + (-8) = ?
16的二进制表示是 00010000,所以用直觉表示法,加法就要写成:
 00010000
+10001000
---------
 10011000
可以看到,如果按照正常的加法规则,就会得到10011000的结果,转成十进制就是-24。显然,这是错误的答案。也就是说,在这种情况下,正常的加法规则不适用于正数与负数的加法,因此必须制定两套运算规则,一套用于正数加正数,还有一套用于正数加负数。从电路上说,就是必须为加法运算做两种电路。
现在,再来看2的补码表示法。
 00010000
+11111000
---------
100001000
可以看到,按照正常的加法规则,得到的结果是100001000。注意,这是一个9位的二进制数。我们已经假定这是一台8位机,因此最高的第9位是一个溢出位,会被自动舍去。所以,结果就变成了00001000,转成十进制正好是8,也就是16 + (-8) 的正确答案。这说明了,2的补码表示法可以将加法运算规则,扩展到整个整数集,从而用一套电路就可以实现全部整数的加法。

补码的本质:

要将正数转成对应的负数,其实只要用0减去这个数就可以了。比如,-8其实就是0-8。
已知8的二进制是00001000,-8就可以用下面的式子求出:
 00000000
-00001000
---------
因为00000000(被减数)小于0000100(减数),所以不够减。请回忆一下小学算术,如果被减数的某一位小于减数,我们怎么办?很简单,问上一位借1就可以了。
所以,0000000也问上一位借了1,也就是说,被减数其实是100000000,算式也就改写成:
100000000
-00001000
---------
 11111000
进一步观察,可以发现100000000 = 11111111 + 1,所以上面的式子可以拆成两个:
 11111111
-00001000
---------
 11110111
+00000001
---------
 11111000
补码的两个转换步骤就是这么来的。(其中的 1111 1000 就是-8的补码,是由对 000 1000 取反得到111 0111 加1 最终得到 111 1000,最后加上符号位1就是1111 1000)。这就是补码计算规则的由来。
  • 23
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
对于这个课程设计题目,您需要设计一个能够进行16位补码加减运算的电路,并提供相应的代码。以下是一个基本的思路和代码示例,供您参考: 1. 设计电路框图 首先,您需要设计一个电路框图,以实现16位补码加减运算。该电路需要包括以下模块: - 输入模块:用于接收两个16位的补码数值。 - 符号位比较模块:用于比较两个数值的符号位,以确定加法或减法运算。 - 补码转换模块:用于将输入的数值转换为补码形式。 - 加法/减法模块:用于进行16位的加法或减法运算。 - 进位/借位处理模块:用于处理进位和借位的情况。 - 输出模块:用于输出运算结果。 2. 编写 Verilog 代码 根据上述电路框图,您可以编写相应的 Verilog 代码,以实现16位补码加减运算。以下是一个简单的代码示例,供您参考: ```verilog module add_sub_16bit( input [15:0] a, input [15:0] b, input sub, output reg [15:0] result ); // 补码转换模块 assign a = sub ? ~(a - 1) : a; assign b = sub ? ~(b - 1) : b; // 加法/减法模块 always @(*) begin if (sub) result = a - b; else result = a + b; end // 进位/借位处理模块 always @(result) begin if (sub) begin if (result[15] == 1) result = result - 1; end else begin if (result[15] == 0) result = result + 1; end end endmodule ``` 这段代码实现了一个名为 add_sub_16bit 的模块,该模块包含三个输入端口:a,b 和 sub,以及一个输出端口 result。其中,a 和 b 分别为两个16位的补码数值,sub 为一个用于指定加法或减法运算的标志位(1 表示减法,0 表示加法)。result 为运算结果,也是一个16位的补码数值。 3. 进行仿真和验证 最后,您需要对这个电路进行仿真和验证,以确保它能够正确地执行16位补码加减运算。您可以使用 Verilog 仿真工具,如 ModelSim 或 Icarus Verilog,对这个电路进行仿真,并进行一系列测试,以验证其正确性。 以上是一个基本的思路和代码示例,供您参考。您可以根据具体情况进行修改和优化,以满足您的课程设计要求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值