You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中用模拟逻辑门实现正确的二进制减法?

修复二进制减法的逻辑问题

你的代码存在三个核心问题:逻辑门的方法定义错误、全减器的借位计算逻辑不正确,以及多余的最高位处理步骤。以下是具体修复方案:

1. 修正逻辑门的方法定义

你的逻辑门execute方法未使用静态方法装饰器,直接通过类调用时会把类本身作为第一个参数传入,导致参数匹配错误。需要给每个门的execute方法添加@staticmethod:

class ANDGate:
    @staticmethod
    def execute(a, b):
        result = ""
        for bit_a, bit_b in zip(a, b):
            result += '1' if bit_a == '1' and bit_b == '1' else '0'
        return result


class ORGate:
    @staticmethod
    def execute(a, b):
        result = ""
        for bit_a, bit_b in zip(a, b):
            result += '1' if bit_a == '1' or bit_b == '1' else '0'
        return result


class XORGate:
    @staticmethod
    def execute(a, b):
        result = ""
        for bit_a, bit_b in zip(a, b):
            result += '1' if (bit_a == '1' and bit_b == '0') or (bit_a == '0' and bit_b == '1') else '0'
        return result


class NOTGate:
    @staticmethod
    def execute(a):
        result = ""
        for bit_a in a:
            result += '0' if bit_a == '1' else '1'
        return result

2. 修正减法函数的全减器逻辑

全减器的借位输出(borrow_out)公式错误,正确的借位逻辑应该是:
borrow_out = (NOT a AND b) OR (NOT a AND borrow_in) OR (b AND borrow_in)
同时需要移除多余的最高位处理步骤——循环已经覆盖了所有位的计算,额外处理会破坏正确结果。

修复后的subtract函数:

def subtract(a, b):
    result = ""
    borrow = '0'
    max_len = max(len(a), len(b))

    # 给较短的操作数补前导零
    a = a.zfill(max_len)
    b = b.zfill(max_len)

    for bit_a, bit_b in zip(reversed(a), reversed(b)):
        # 计算当前位差值:a XOR b XOR 输入借位
        diff = XORGate.execute(XORGate.execute(bit_a, bit_b), borrow)
        
        # 计算新的借位:(NOT a AND b) OR (NOT a AND 输入借位) OR (b AND 输入借位)
        not_a = NOTGate.execute(bit_a)
        term1 = ANDGate.execute(not_a, bit_b)
        term2 = ANDGate.execute(not_a, borrow)
        term3 = ANDGate.execute(bit_b, borrow)
        borrow = ORGate.execute(ORGate.execute(term1, term2), term3)
        
        result = diff + result
        print(f"bit_a: {bit_a}, bit_b: {bit_b}, diff: {diff}, borrow: {borrow}, result: {result}")

    # 去除前导零,若结果全为零则保留一个零
    result = result.lstrip('0') or '0'

    return result

3. 测试验证

调用subtract('101010', '1100')会得到正确结果11110,调试输出的借位传递过程如下:

bit_a: 0, bit_b: 0, diff: 0, borrow: 0, result: 0
bit_a: 1, bit_b: 0, diff: 1, borrow: 0, result: 10
bit_a: 0, bit_b: 1, diff: 1, borrow: 1, result: 110
bit_a: 1, bit_b: 1, diff: 1, borrow: 1, result: 1110
bit_a: 0, bit_b: 0, diff: 1, borrow: 1, result: 11110
bit_a: 1, bit_b: 0, diff: 0, borrow: 0, result: 011110

最终去除前导零后得到11110,与预期一致。

内容的提问来源于stack exchange,提问作者TheCodingGolfer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 03:50:00