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

C++十进制转二进制求和乘积代码sum/product函数运行异常求助

调试十进制转二进制及求和乘积代码的问题分析与修复

核心问题分析

  • log2浮点数精度误差:当输入是2的幂(如512=2^9)时,log2(512)可能因浮点数精度问题返回8.9999999999,转换为int后变成8,加1得到9,但实际512的二进制需要10位,导致binary数组长度不足,后续操作越界。
  • binary数组未初始化:binary函数仅填充了余数部分,未处理的数组元素是随机值,会干扰后续计算。
  • sum函数越界修改原数组:sum中直接对a[i]、b[i]赋值(当i>=原数组长度时),属于越界访问,触发未定义行为(如崩溃、数据错乱)。
  • 变长数组(VLA)非标准:sum中的int p[z + 1] = {};是C风格变长数组,C++标准不支持,部分编译器可能报错或出现异常。
  • product函数指针赋值错误:sop = {};、q = {};这种赋值方式会使动态分配的指针丢失指向,造成内存泄漏,同时访问空指针会直接崩溃。
  • product数组未初始化:每次循环创建的q数组未将未使用的位置置0,导致求和时引入随机值。

修复后的完整代码

#include <iostream>
#include <cmath>
using namespace std;

int* binary(int num, int bits);
int* sum(int a[], int lenA, int b[], int lenB);
int* product(int a[], int lenA, int b[], int lenB);
void display(int arr[], int len);
int getBitLength(int num); // 新增:计算二进制位数,避免浮点数误差

int main()
{
    int x, y;
    cout << "Enter two decimal numbers:\n";
    cin >> x >> y;

    int t = getBitLength(x);
    int* a = binary(x, t);
    cout << "Binary: ";
    display(a, t);

    int u = getBitLength(y);
    int* b = binary(y, u);
    cout << "\nBinary: ";
    display(b, u);

    int* c = sum(a, t, b, u);
    int sumLen = max(t, u) + 1;
    cout << "\nSum: ";
    display(c, sumLen);

    int* d = product(a, t, b, u);
    int productLen = t + u;
    cout << "\nProduct: ";
    display(d, productLen);

    // 释放动态分配的内存,避免泄漏
    delete[] a;
    delete[] b;
    delete[] c;
    delete[] d;
    return 0;
}

// 计算二进制位数,确保准确
int getBitLength(int num) {
    if (num == 0) return 1;
    int len = 0;
    while (num > 0) {
        len++;
        num /= 2;
    }
    return len;
}

int* binary(int num, int bits)
{
    int* arr = new int[bits](); // 初始化所有元素为0
    int i = 0;
    int n = num;
    while (n > 0 && i < bits) {
        arr[i++] = n % 2;
        n /= 2;
    }
    return arr;
}

void display(int arr[], int len)
{
    // 找到第一个非零的最高位,避免输出前置0
    int start = len - 1;
    while (start >= 0 && arr[start] == 0) {
        start--;
    }
    // 如果全是0,输出一个0
    if (start < 0) {
        cout << 0;
        return;
    }
    for (int i = start; i >= 0; i--) {
        cout << arr[i];
    }
}

int* sum(int a[], int lenA, int b[], int lenB)
{
    int maxLen = max(lenA, lenB);
    int sumLen = maxLen + 1;
    int* result = new int[sumLen](); // 初始化结果数组为0
    int carry = 0;

    for (int i = 0; i < maxLen; i++) {
        int bitA = (i < lenA) ? a[i] : 0;
        int bitB = (i < lenB) ? b[i] : 0;
        int total = bitA + bitB + carry;
        
        result[i] = total % 2;
        carry = total / 2;
    }
    // 处理最后的进位
    if (carry != 0) {
        result[maxLen] = carry;
    }
    return result;
}

int* product(int a[], int lenA, int b[], int lenB)
{
    int productLen = lenA + lenB;
    int* result = new int[productLen](); // 初始化结果为0

    for (int i = 0; i < lenA; i++) {
        if (a[i] == 0) continue; // 跳过0位,优化计算
        int* temp = new int[productLen](); // 临时存储当前位的乘积
        for (int j = 0; j < lenB; j++) {
            temp[i + j] = a[i] * b[j];
        }
        // 把临时乘积加到结果里
        int* tempSum = sum(result, productLen, temp, productLen);
        delete[] result;
        delete[] temp;
        result = tempSum;
    }
    return result;
}

关键修复说明

  1. 替换log2为整数位数计算:新增getBitLength函数,用循环计算二进制位数,彻底避免浮点数精度问题。
  2. 初始化数组为0:所有动态分配的数组都用new int[N]()初始化,确保未使用的位置都是0。
  3. sum函数避免修改原数组:通过临时变量获取a、b的对应位,不再越界修改原数组。
  4. 修复product的指针错误:取消错误的指针赋值,改用动态数组初始化,同时每次循环清理临时内存,避免泄漏。
  5. 优化display函数:正确跳过前置0,同时处理全0的情况。
  6. 添加内存释放:main函数中释放所有动态分配的内存,避免内存泄漏。

内容的提问来源于stack exchange,提问作者محمد محمدنژاد

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 00:27:02