二进制移位实现加减乘除

如何使用位操作分别实现整数的加减乘除四种运算?

2. 解决方案

需要熟练掌握一些常见功能的位操作实现,具体为:

<1> 常用的等式:-n = ~(n-1) = ~n+1

<2> 获取整数n的二进制中最后一个1:n&(-n) 或者 n&~(n-1),如:n=010100,则-n=101100,n&(-n)=000100

<3> 去掉整数n的二进制中最后一个1:n&(n-1),如:n=010100,n-1=010011,n&(n-1)=010000

(1) 加法实现

可以很容易地用“异或”和“或”操作实现整数加法运算:对应位数的“异或操作”可得到该位的数值,对应位的“与操作”可得到该位产生的高位进位,如:a=010010,b=100111,计算步骤如下:

第一轮:a^b=110101,(a&b)<<1=000100, 由于进位(000100)大于0,则进入下一轮计算,a=110101,b=000100,a^b=110001,(a&b)<<1=001000,由于进位大于0,则进入下一轮计算:a=110001,b=001000,a^b=111001,(a&b)<<1=0,进位为0,终止,计算结果为:111001。

代码如下:

 

intadd(inta, intb) {

  intcarry, add;

  do{

    add = a ^ b;

    carry = (a & b) << 1;

    a = add;

    b = carry;

  }while(carry != 0);

  returnadd;

}

 

 

 

(2) 减法实现

减法可很容易地转化为加法:a - b = a + (-b) = a + (~b + 1 )

代码如下:

 

intsubtract(inta, intb) {

  returnadd(a, add(~b, 1));

}

 

 

 

(3) 乘法实现

先看一个实例:1011*1010:

 

1011

   * 1010

 ----------

    10110 < 左移一位,乘以0010

+ 1011000 < 左移3位,乘以1000

----------

  1101110

 

因而乘法可以通过系列移位和加法完成。最后一个1可通过b&~(b-1)求得,可通过b& (b-1)去掉,为了高效地得到左移的位数,可提前计算一个map,代码如下:

 

 

intmultiply(inta, intb) {

  boolneg = (b < 0);

  if(b < 0)

    b = -b;

  intsum = 0;

  map<int,int> bit_map;

  for(inti = 0; i < 32; i++)

    bit_map.insert(pair<int,int>(1 << i, i));

    while(b > 0) {

      intlast_bit = bit_map[b & ~(b - 1)];

      sum += (a << last_bit);

      b &= b - 1;

    }

  if(neg)

    sum = -sum;

  returnsum;

}

 

 

(4) 除法实现

乘法可很容易转化为减法操作,主要思想与乘法实现类似,代码如下:

 

intdivide(inta, intb) {

  boolneg = (a > 0) ^ (b > 0);

  if(a < 0)

    a = -a;

  if(b < 0)

    b = -b;

  if(a < b)

    return0;

  intmsb = 0;

  for(msb = 0; msb < 32; msb++) {

    if((b << msb) >= a)

      break;

  }

  intq = 0;

  for(inti = msb; i >= 0; i--) {

    if((b << i) > a)

      continue;

    q |= (1 << i);

    a -= (b << i);

  }

  if(neg)

    return-q;

  returnq;

}

<think>我们已经在之前的讨论中了解了如何使用基本门电路构建加法器(半加器、全加器)和补码器。现在,我们将基于这些基础组件构建二进制数的加减乘除运算电路。由于Logisim是一个逻辑电路仿真工具,我们将使用组合逻辑和时序逻辑来实现这些运算。 ###1.加法运算我们已经知道如何构建4位加法器(通过级联全加器)。回顾一下: -**半加器**:输入两个1位二进制数,输出和(Sum)和进位(Carry)。电路由异或门(和)和与门(进位)组成。 -**全加器**:输入两个1位二进制数及低位进位,输出和及进位。可由两个半加器和一个或门构成。- **4位加法器**:将4个全加器级联,低位进位输出连接到高位进位输入。在Logisim中,我们可以直接使用内置的加法器组件(位于Arithmetic库中),但若要求用基本门电路实现,则需自行构建全加器并级联。 ###2.减法运算减法可以通过加法来实现,即使用补码。对于二进制数,负数的补码等于其反码加1。因此,减法A-B可以转化为A加上B的补码(即A+ (-B))。具体步骤:1.构建一个补码器电路(用于计算B的补码):-对B的每一位取反(使用非门)。-然后加上1(可以通过将取反后的结果输入加法器,另一个输入设为1来实现)。 2.将A和B的补码输入加法器,得到的结果即为差(注意:如果最高位有进位,在补码运算中应忽略,因为补码是模运算)。 在4位补码系统中,结果也是4位(忽略进位),但要注意溢出问题。###3.乘法运算二进制乘法可以通过加法和移位实现。以两个4位二进制数相乘为例(结果最多8位):-方法:类似于手算乘法,将被乘数分别与乘数的每一位相乘(相当于逻辑与),然后将这些部分积左移相应的位数后相加。-具体步骤:1.初始化一个8位的累加器(初始为0)。2.从乘数的最低位开始,如果当前位为1,则将累加器加上被乘数(注意:被乘数需要左移到正确的位置);如果为0,则不加。3.然后将被乘数左移一位,乘数右移一位(或反之),重复上述过程直到乘数为0。在Logisim中,我们可以通过组合电路实现,但更常见的是用时序电路(使用寄存器、移位器和加法器)来实现乘法器。不过,对于4位乘法器,也可以直接设计组合逻辑: -部分积的产生:乘数的每一位与被乘数的每一位相与,得到4个部分积(每个部分积4位,但根据乘数位的位置需要左移0位、1位、2位、3位)。-然后将这4个部分积相加(使用多个加法器级联)。 例如,被乘数A(a3a2a1a0),乘数B(b3b2b1b0):-部分积0:b0* A(左移0位)->0000a3b0a2b0a1b0a0b0(实际上需要扩展到8位:0000 a3b0 a2b0 a1b0 a0b0)-部分积1:b1* A(左移1位)->000 a3b1 a2b1 a1b1 a0b10-部分积2:b2* A(左移2位)->00 a3b2 a2b2 a1b2 a0b200-部分积3:b3* A(左移3位)->0 a3b3 a2b3 a1b3 a0b3000-将这四个8位的部分积相加,得到一个8位的乘积。在Logisim中,我们可以使用多个4位加法器扩展为8位加法器来逐步相加。###4.除法运算二进制除法可以通过减法和移位实现(恢复余数法或不恢复余数法)。以4位二进制数除以4位二进制数为例(商和余数各4位):-方法:类似于手算除法,从被除数的高位开始,逐位尝试减去除数,如果够减则商1,否则商0,并将余数左移一位,再与除数比较。-具体步骤(恢复余数法):1.初始化余数寄存器(8位,初始为被除数扩展为8位,高位补0),除数寄存器(8位,低4位为除数,高4位补0),商寄存器(4位,初始为0)。2.重复4次(因为除数是4位):a.将余数左移1位(高位丢弃,最低位补0)。b.用余数的高4位减去除数的高4位(实际上除数在整个8位中,但高4位为0,所以相当于减除数)。c.如果结果大于等于0,则商的最低位设为1,并将减法结果存入余数的高4位(同时余数的低4位左移时已经移入了一位被除数)。d.否则,商的最低位设为0,并恢复余数(即不保留减法结果,保持原余数)。3.最后,余数寄存器的高4位就是最终的余数,商寄存器就是商。在Logisim中实现除法器较为复杂,需要用到减法器(实际上用加法器做补码减法)、移位寄存器和控制逻辑(用于判断是否恢复余数)。通常用时序电路实现。###实现建议在Logisim中,我们可以分别构建加法器、补码器(用于减法)、乘法器(组合或时序)和除法器(时序)。由于时间限制,这里重点描述加减乘的电路,除法器较为复杂,可参考恢复余数法设计。 ####加法器电路(4位)-使用4个全加器级联,每个全加器的进位输出连接到下一个的进位输入。 ####减法器电路(4位)-先构建一个补码器:对输入B的每一位取反(非门),然后加1(可以连接一个加法器,一个输入为取反后的B,另一个输入为0001)。-然后将A和B的补码输入4位加法器,加法器的输出即为差(忽略进位)。####乘法器电路(4位组合逻辑) 1.生成部分积:对乘数B的每一位,使用4个与门分别与被乘数A的每一位相与,得到4个4位的部分积。2.将部分积根据乘数位的位置左移(即低位部分积左移0位,下一位左移1位,依此类推)。左移操作可以通过在低位补0实现,扩展为8位。 3.将4个8位的部分积相加:使用三个8位加法器(或级联多个4位加法器扩展为8位)进行两两相加。 ####除法器电路(4位时序逻辑) 由于组合逻辑实现除法器非常复杂,通常用时序逻辑(使用寄存器、减法器、移位器等)实现。步骤: 1.初始化:-余数寄存器(8位):高4位为0,低4位为被除数。-除数寄存器(8位):高4位为除数,低4位为0(或除数放在低4位,高4位为0,取决于设计)。-商寄存器(4位):0。-计数器:4。2.循环(4次):a.将余数寄存器左移1位(最高位移入商寄存器的最低位?注意:具体设计有多种,这里描述一种:将余数寄存器和商寄存器一起组成一个8+4=12位的移位寄存器,但为简化,也可以分开处理)。b.用余数寄存器的高4位减去除数寄存器的高4位(或减去除数,因为除数在高4位,低4位为0,所以相当于减除数)。c.如果结果非负(即没有借位),则:-将减法结果存回余数寄存器的高4位。-将商寄存器的最低位设为1。d.否则,恢复余数(即不做改变),将商寄存器的最低位设为0。e.计数器减1,若计数器不为0则回到a。 3.最后,商寄存器即为商,余数寄存器的高4位即为余数(注意:余数寄存器在移位过程中已经改变了,最后需要右移恢复?或者调整初始设置,这里不展开详细设计)。 由于除法器设计较为复杂,建议参考教材或在线资料。 ###总结在Logisim中实现二进制运算,需要充分利用已经构建的加法器、补码器等基础组件。加减法相对简单,乘法和除法需要更复杂的电路。乘法器可以用组合逻辑实现(但电路规模随位数增加而快速增大),而除法器通常用时序逻辑实现。§§相关问题§§1.如何在Logisim中构建一个4位全加器?2.补码减法电路的具体实现步骤是什么?3.如何用组合逻辑实现4位二进制乘法器? 4.恢复余数除法器的工作原理是什么?</think>### 在Logisim中实现二进制加减乘除运算的完整方案 #### 一、加法运算实现 1. **基础组件** - **半加器**:用异或门计算和($S = A \oplus B$),与门计算进位($C_{out} = A \cdot B$)[^2] - **全加器**:由两个半加器构成,处理进位输入($C_{in}$) $$S = (A \oplus B) \oplus C_{in}$$ $$C_{out} = (A \cdot B) + (C_{in} \cdot (A \oplus B))$$ 2. **4位加法器电路** - 级联4个全加器,低位进位输出连接高位进位输入 - 输入:两个4位二进制数 $A_3A_2A_1A_0$ 和 $B_3B_2B_1B_0$ - 输出:4位和 $S_3S_2S_1S_0$ + 最终进位 $C_3$ - **扩展**:添加溢出检测($V = C_3 \oplus C_2$) #### 二、减法运算实现(补码法) 1. **补码转换** - 正数补码 = 原码 - 负数补码 = 反码 + 1 $$-B = \overline{B} + 1$$ 例:$-1101_2$ 的补码 = $11110011_2$[^3] 2. **4位减法器电路** ```mermaid graph LR A[被减数A] --> Adder B[减数B] --> NOT[取反电路] --> Inc[加1电路] --> Adder Adder(4位加法器) --> Result[差] Zero[进位输入=1] --> Adder ``` - 关键组件: - **取反电路**:4个非门 - **加1电路**:最低位全加器的 $C_{in}=1$ - 结果:$A - B = A + (-B)_{补码}$(忽略最高位进位) #### 三、乘法运算实现移位加法) 1. **乘法原理** $$A \times B = \sum_{i=0}^{n-1} (A \cdot b_i) \times 2^i$$ 例:$1101_2 \times 0101_2 = (1101<<2) + (1101<<0) = 65_{10}$[^4] 2. **4位乘法器电路** ```mermaid graph TB Multiplier[乘数B] --> Control Multiplicand[被乘数A] --> Shifter[移位器] Shifter --> AND[与门阵列] Control[时序控制器] --> Shifter AND --> AdderTree[加法器树] AdderTree --> Product[8位乘积] ``` - 实现步骤: 1. 用4组与门生成部分积($A \& b_i$) 2. 部分积左移对应位数($b_0$不移,$b_1$移1位等) 3. 通过3个4位加法器级联相加部分积 #### 四、除法运算实现(恢复余数法) 1. **算法流程** ``` 初始化:余数寄存器 = 被除数(高位补0) FOR i=1 to 4: 1. 余数左移1位 2. 余数高位减除数 3. 若结果≥0:商置1,更新余数 否则:商置0,恢复余数 ``` 2. **4位除法器电路** ```mermaid graph LR Dividend[被除数] --> Init Divisor[除数] --> SUB[减法器] Init[初始化寄存器] --> Shifter[移位器] Shifter --> SUB SUB --> Check{符号位} Check --≥0--> Update[更新余数] Check --<0--> Restore[恢复余数] Update --> Quotient[商寄存器] Restore --> Quotient ``` - 关键组件: - 8位移位寄存器(存余数) - 4位补码减法器(计算余数-除数) - 控制单元(生成时序信号) #### 五、集成运算单元设计建议 1. **统一数据通路** - 4位数据总线 + 操作码选择器(OP=00加/01减/10乘/11除) - 共享加法器/减法器核心模块 2. **扩展功能** - 添加溢出/除零检测电路 - 支持符号位(补码运算) - 添加结果寄存器存储输出 > **实现提示**:在Logisim中优先构建全加器和补码转换模块,乘法/除法复用这些基础组件。时序电路需使用时钟驱动寄存器[^1][^2]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值