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

JavaScript无位运算符实现全减器结果异常修复问询

全减器借位错误修复方案

我尝试在JavaScript中不使用位运算符实现位操作,全加器做起来挺简单,但全减器出问题了。调用BitSubtractor(8, '100', '10')计算100减10时,预期结果是[0,0,0,0,0,0,1,0],但实际得到[0,0,0,0,1,0,1,0],明显多了个借位,求修复方案。

相关实现代码如下:

function BitSubtractor(bits, A, B){
    try{
        A = getBinaryArray(A);
        B = getBinaryArray(B);
        if(A.length > bits || B.length > bits)
            throw new SyntaxError(
                'Number of bits must be less than or equal to ' + bits + ' bits\n' + 
                'A: ' + A.length + ' bits\n' +
                'B: ' + B.length + ' bits'
            );
    }catch(e){
        throw e;
    }

    if(A.length < bits || B.length < bits){
        while(A.length < bits)
            A.unshift(0);
        while(B.length < bits)
            B.unshift(0);
    }

    console.log(A, B)

    let result = [];
    let borrow = 0;

    for(let i = bits - 1; i >= 0; i--){
        let a = Number(A[i]);
        let b = Number(B[i]);
        let FS = new Subtractor(a, b, borrow);
        result.unshift(FS.DIFF);
        borrow = FS.BORROW;
        // console.log(a, b, FS)
    }

    let overflow = [];
        overflow.unshift(borrow);
        while(overflow.length < bits)
            overflow.unshift(0);

    // let negative = borrow ? true : false;
    return {diff: result, overflow, borrow/* , negative */};
};
function Subtractor(A, B, Bin = 0){
    if(!checkValue(A) || !checkValue(B) || !checkValue(Bin))
        throw new Error('A, B, and Bin must be boolean');
    
    // DIFF = A XOR B XOR Bin
    // this.DIFF = (A ^ B ^ Bin) ? 1 : 0;
    let AB_XOR     = Gate.XOR(A, B);
    let AB_Bin_XOR = Gate.XOR(AB_XOR, Bin);

    // BORROW = (!A AND B) OR (B AND Bin) OR (A AND Bin)
    // this.BORROW = (!A & B) | (B & Bin) | (A & Bin) ? 1 : 0;
    let A_NOT     = Gate.NOT(A);
    let B_NOT     = Gate.NOT(B);
    let Bin_NOT   = Gate.NOT(Bin);
    let A_NOT_AND = Gate.AND(A_NOT, B);
    let B_AND_Bin = Gate.AND(B, Bin);
    let A_AND_Bin = Gate.AND(A, Bin);
    let OR_1      = Gate.OR(A_NOT_AND, B_AND_Bin);
    let OR_2      = Gate.OR(OR_1, A_AND_Bin);

    this.DIFF   = AB_Bin_XOR;
    this.BORROW = OR_2;
    return this;
};
function Transistor(input, type){
    if(!checkValue(input))
        throw new Error('IN must be boolean');

    if(input === '0') input = Number(input);

    this.IN = toBoolean(input);
    this.OUT = this.IN;

    if(type === 'NOT')
        this.OUT = !this.OUT;

    return this.OUT;
};

function Gate(A, B, type){
    const inputA = new Transistor(A);
    const inputB = new Transistor(B);
    this.IN1 = inputA.OUT;
    this.IN2 = inputB.OUT;
    this.OUT = null;

    if(type === 'AND'){
        this.OUT = this.IN1 && this.IN2;
    }
    if(type === 'OR'){
        this.OUT = this.IN1 || this.IN2;
    }
    if(type === 'XOR'){
        this.OUT = (this.IN1 || this.IN2) && !(this.IN1 && this.IN2);
        // this.OUT = (!this.IN1 && this.IN2) || (this.IN1 && !this.IN2);
    }

    if(this.OUT !== null)
        return toBinary(this.OUT);
};

// Bitwise Operators
Gate.BitAND = (A, B) => A & B;
Gate.BitOR  = (A, B) => A | B;
Gate.BitXOR = (A, B) => A ^ B;
Gate.BitNOT = A => ~A;

Gate.AND = (A, B) => Gate(A, B, 'AND');
// Gate.NAND = (A, B) => Gate(A, B, 'AND') ? 0 : 1;
Gate.OR  = (A, B) => Gate(A, B, 'OR');
// Gate.NOR = (A, B) => Gate(A, B, 'OR') ? 0 : 1;
Gate.XOR = (A, B) => Gate(A, B, 'XOR');
Gate.NOT = A => Transistor(A, 'NOT');

问题根源

错误出在Subtractor函数的借位计算公式上。你当前使用的公式:

BORROW = (!A AND B) OR (B AND Bin) OR (A AND Bin)

逻辑错误,其中A AND Bin的分支会导致不该产生借位的场景误生成借位。

全减器的正确借位逻辑是:当被减数A小于B + Bin时,向高位借位,对应的正确公式为:

BORROW = (!A AND B) OR (!A AND Bin) OR (B AND Bin)

修复后的Subtractor函数

function Subtractor(A, B, Bin = 0){
    if(!checkValue(A) || !checkValue(B) || !checkValue(Bin))
        throw new Error('A, B, and Bin must be boolean');
    
    // DIFF = A XOR B XOR Bin 这部分逻辑是对的,无需修改
    let AB_XOR     = Gate.XOR(A, B);
    let AB_Bin_XOR = Gate.XOR(AB_XOR, Bin);

    // 修正后的借位计算公式
    let A_NOT          = Gate.NOT(A);
    let A_NOT_AND_B    = Gate.AND(A_NOT, B);
    let A_NOT_AND_Bin  = Gate.AND(A_NOT, Bin);
    let B_AND_Bin      = Gate.AND(B, Bin);
    let OR_1           = Gate.OR(A_NOT_AND_B, A_NOT_AND_Bin);
    let OR_2           = Gate.OR(OR_1, B_AND_Bin);

    this.DIFF   = AB_Bin_XOR;
    this.BORROW = OR_2;
    return this;
};

验证修复效果

修复后调用BitSubtractor(8, '100', '10'):

  • A补全8位为[0,0,0,0,0,1,0,0],B补全为[0,0,0,0,0,0,1,0]
  • 逐位计算时,第三位(从右数第3位)的借位会被正确计算为0,最终结果就是预期的[0,0,0,0,0,0,1,0]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 17:25:53