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

二进制减法计算器开发求助:结果异常及补码计算错误

Binary Subtraction Calculator Issues: Fixing Negative Outputs & Incorrect Results

Hey there! Let's break down why your binary subtraction code is giving wonky results, and fix it up properly.

First, let's outline the core problems in your current code:

  • Negative values in output: When the current bit of a is smaller than b (like 0 - 1), (a%10 - b%10 + r) becomes negative. In C++, negative numbers mod 2 return negative results (e.g., -1 % 2 = -1), which is why you see -1 in your output.
  • Incorrect borrow calculation: Your borrow logic r = (a%10 - b%10 + r)/2 fails for negative values. For example, if the calculation gives -1, integer division by 2 returns 0 instead of the correct borrow value (-1 to indicate we need to borrow from the next higher bit).
  • Missing proper two's complement implementation: You mentioned trying two's complement but didn't integrate it into your code—right now you're doing raw binary subtraction, not leveraging the complement method to avoid negative numbers entirely.

Fixed Code Using Two's Complement

Here's a revised version that correctly handles binary subtraction by converting it to addition with two's complement (the standard method for binary subtraction):

#include <iostream>
#include <algorithm> // For reverse
using namespace std;

// Convert decimal number to binary array
void decToBinary(int num, int binary[], int &length) {
    length = 0;
    if (num == 0) {
        binary[length++] = 0;
        return;
    }
    while (num > 0) {
        binary[length++] = num % 2;
        num /= 2;
    }
    reverse(binary, binary + length);
}

// Calculate two's complement of a binary array
void twosComplement(int binary[], int length, int complement[], int &compLength) {
    compLength = length;
    // Step 1: Get one's complement (flip all bits)
    for (int i = 0; i < length; i++) {
        complement[i] = 1 - binary[i];
    }
    // Step 2: Add 1 to get two's complement
    int carry = 1;
    for (int i = length - 1; i >= 0 && carry; i--) {
        int sum = complement[i] + carry;
        complement[i] = sum % 2;
        carry = sum / 2;
    }
    // Handle extra carry if needed (expand array)
    if (carry) {
        for (int i = compLength; i > 0; i--) {
            complement[i] = complement[i-1];
        }
        complement[0] = carry;
        compLength++;
    }
}

// Add two binary arrays
void addBinary(int a[], int aLen, int b[], int bLen, int result[], int &resLen) {
    resLen = max(aLen, bLen);
    int carry = 0;
    // Pad shorter array with leading zeros to match lengths
    for (int i = resLen - 1; i >= 0; i--) {
        int bitA = (i >= resLen - aLen) ? a[i - (resLen - aLen)] : 0;
        int bitB = (i >= resLen - bLen) ? b[i - (resLen - bLen)] : 0;
        
        int sum = bitA + bitB + carry;
        result[i] = sum % 2;
        carry = sum / 2;
    }
    // Add final carry if present
    if (carry) {
        for (int i = resLen; i > 0; i--) {
            result[i] = result[i-1];
        }
        result[0] = carry;
        resLen++;
    }
}

int main() {
    int decA, decB;
    cout << "1st number (decimal): ";
    cin >> decA;
    cout << "2nd number (decimal): ";
    cin >> decB;

    int binaryA[20], lenA;
    int binaryB[20], lenB;
    decToBinary(decA, binaryA, lenA);
    decToBinary(decB, binaryB, lenB);

    // Convert subtraction to addition: A - B = A + (-B) (using two's complement of B)
    int compB[20], compLenB;
    twosComplement(binaryB, lenB, compB, compLenB);

    int result[20], resLen;
    addBinary(binaryA, lenA, compB, compLenB, result, resLen);

    // Remove leading zeros (keep one zero if result is 0)
    int startIdx = 0;
    while (startIdx < resLen - 1 && result[startIdx] == 0) {
        startIdx++;
    }

    cout << "Difference (binary): ";
    for (int i = startIdx; i < resLen; i++) {
        cout << result[i];
    }
    cout << endl;

    system("pause");
    return 0;
}

How This Fixes Your Example

Let's test your case: 50 (110010) minus 30 (11110):

  1. We pad 30's binary to 6 bits: 011110
  2. Calculate its two's complement: flip bits to 100001, add 1 to get 100010
  3. Add 110010 + 100010 = 1010100
  4. Discard the leading carry (since we're working with positive results), leaving 010100—which is 20 in decimal, the correct answer!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 12:37:50