如何为这个使用数组的bigint类重载+运算符? C ++

时间:2018-03-22 09:31:39

标签: c++ xcode data-structures biginteger bigint

我目前正在使用C ++进行在线数据结构课程,我正在开展一个个人项目,以帮助我更好地理解基础知识。我正在研究的项目是bigint类的实现,这个类支持使用数组而不是向量或字符串来存储和计算任意精度的整数。我正在努力实现主要算术运算符。

数字从最低位到最高位数存储在数组中(201将存储为{1,0,2}),计算也按此顺序执行。

我找到了一些与此相关的材料,但绝大多数使用矢量/字符串并没有帮助我。其他一些资源(例如thisthis)确实有所帮助,但在我尝试在我的代码中实现它们时却无效。例如,这个实现加法运算符的代码不起作用,我得到一个bad_alloc异常或答案是错误的,但我似乎无法弄清楚为什么或如何解决它,我一直在它好几天了:

bigint& operator+(const bigint& lhs, const bigint& rhs){
    bool minus_sign = rhs.is_negative();
    size_t amt_used = 0;    // to keep track of items in the array

    // initial size and size of resulting array
    // set initial size to the size of the larger array
    // set result_size to ini size plus one in case of carry
    size_t ini_size = lhs.get_digit_count() > rhs.get_digit_count() ?
                                lhs.get_digit_count() : rhs.get_digit_count();
    const size_t INITIAL_SIZE = ini_size;
    const size_t RESULT_SIZE = INITIAL_SIZE+1;

    uint8_t temp[RESULT_SIZE],  // temporary array
            result_arr[RESULT_SIZE],
            lhs_arr[INITIAL_SIZE], rhs_arr[INITIAL_SIZE]; // new arrays for lhs/rhs of the same size to avoid overflow if one is smaller

    //assign corresponding values to the new arrays
    for (size_t i = 0; i < lhs.get_digit_count(); i++){
        lhs_arr[i] = lhs.get_digit(i);
    }

    for (size_t i = 0; i < rhs.get_digit_count(); i++){
        rhs_arr[i] = rhs.get_digit(i);
    }

    // perform addition
    int carry = 0;  //carry variable
    size_t j = 0;
    for ( ; j < INITIAL_SIZE; j++){
        uint8_t sum = lhs_arr[j] + rhs_arr[j] + carry;

        if (sum > 9){
            result_arr[j] = sum - 10;
            carry = 1;
            amt_used++;
        }
        else{
            result_arr[j] = sum;
            carry = 0;
            amt_used++;
        }
    }

    if (carry == 1){
        result_arr[j] = 1;
        amt_used++;
    }

    // flip the array to most sig to least sig, since the constructor performs a switch to least-most sig.
    size_t decrement_index = amt_used - 1;
    for (int i = 0; i < RESULT_SIZE; i++){
        temp[i] = result_arr[decrement_index];
        decrement_index--;
    }

    for (int i = 0; i < RESULT_SIZE; i++){
        result_arr[i] = temp[i];
    }

    // create new bigint using the just-flipped array and return it
    bigint result(result_arr, amt_used, minus_sign);

    return result;
}

这是我得到的错误:线程1:EXC_BAD_ACCESS(代码= 1,地址= 0x5)

当我刚刚添加8700 + 2100

时,或者我得到一个非常大的数字

1 个答案:

答案 0 :(得分:0)

此代码存在几个问题。

使用VLA扩展(对于temp等)不是标准的C ++。这些基于堆栈的数组未初始化,因此它们将包含随机数据。使用数据填充这些数组时,不会分配给每个元素。例如,当左数比右数短时(这样lhs_arr的几个元素中包含垃圾数据),这会导致垃圾结果。然后,这些错误值将用于加法数组中。使用std::vector将符合标准,并导致向量元素全部初始化为适当的值(如0)。这可能是你的#34;非常大的数字&#34;来自。

当您&#34;翻转阵列&#34;时,decrement_index可能是否定的,如果不是所有结果槽都被使用的话。这可能是导致EXC_BAD_ACCESS崩溃的原因。

返回对局部变量的引用会导致Undefined Behavior,因为当函数返回时会破坏本地,导致悬空引用。这可能是您所述问题的原因之一。

你对负数的处理是完全错误的,因为你根本不能真正处理它们。