首页 > 解决方案 > 实现 Long Integer 类。提供对类的实例执行算术运算的能力

问题描述

我有一个 Long Integer 类的实现,它应该提供对类的实例执行算术运算的能力。它适用于 95% 的情况,但有时会显示错误的结果。错误答案的屏幕位于代码下方。

巨大的Int.h:

#ifndef _HUGEINGH
#define _HUGEINGH
#include <iostream>
#include <list>
#include <string>
#include <math.h>

using namespace std;

class HugeInt {
private:
    char* listNumber;
    int maxLength, length;
    bool plus;
    void expansion_size_length();
    void updatingLength();
    void set_listNumber(int position, char num);
    char get_listNumber(int position);
    char symbol_in_numeral(char symbol);
    char numeral_in_symbol(char numeral);
public:
    string toString();
    void setNumber(string str);
    HugeInt operator-(HugeInt HugeInt);
    HugeInt operator+(HugeInt HugeInt);
    HugeInt operator*(HugeInt HugeInt);
    HugeInt(string str);
    HugeInt();
    HugeInt(const HugeInt &lg);
    ~HugeInt();
};

#endif

Hugeint.cpp:

#include "stdafx.h"
#include "HugeInt.h"


void HugeInt::expansion_size_length() {
    char* tmp = new char[maxLength * 2];
    for (int i = 0; i < maxLength; i++) {
        tmp[i] = listNumber[i];
    }
    delete[] listNumber;
    listNumber = tmp;
    maxLength *= 2;
}

void HugeInt::updatingLength() {
    while (length > 1) {
        int tmp = listNumber[length - 1];
        if (listNumber[length - 1] == 0) {
            length--;
        }
        else {
            return;
        }
    }
}

void HugeInt::set_listNumber(int position, char num) {
    if (position < maxLength) {
        listNumber[position] = num;
        if (position >= length)
            length = position + 1;
    }
    else {
        while (position > maxLength)
            expansion_size_length();
        length = position + 1;
    }
}

char HugeInt::get_listNumber(int position) {
    if (position < length) {
        return listNumber[position];
    }
    return 0;
}

char HugeInt::symbol_in_numeral(char symbol) {
    return symbol - '0';
}

char HugeInt::numeral_in_symbol(char numeral) {
    return numeral + '0';
}

string HugeInt::toString() {
    string str = string();
    if (!plus)
        str.insert(str.size(), 1, '-');
    for (int i = length - 1; i >= 0; i--) {
        str.insert(str.size(), 1, numeral_in_symbol(listNumber[i] / 10));
        str.insert(str.size(), 1, numeral_in_symbol(listNumber[i] % 10));
    }
    return str;
}
void HugeInt::setNumber(string str) {
    //plus = true;
    //maxLength = 10;
    //listNumber = new char[maxLength];
    length = 0; // дело в этом
    delete[] listNumber;
    listNumber = new char[str.length() + 1];
    maxLength = str.length() + 1;

    for (int i = length; i < maxLength; i++)
        listNumber[i] = 0;
    length = maxLength;
    if (str.size() != 0) {
        int k = 0;
        if (str[0] == '-') {
            plus = false;
            for (int i = str.size() - 1; i > 0; i -= 2) {
                if (i - 1 > 0)
                    listNumber[k] = symbol_in_numeral(str[i]) + symbol_in_numeral(str[i - 1]) * 10;
                else listNumber[k] = symbol_in_numeral(str[i]);
                k++;
            }
        }
        else if (str[0] == '+') {
            plus = true;
            for (int i = str.size() - 1; i > 0; i -= 2) {
                if (i - 1 > 0)
                    listNumber[k] = symbol_in_numeral(str[i]) + symbol_in_numeral(str[i - 1]) * 10;
                else listNumber[k] = symbol_in_numeral(str[i]);
                k++;
            }
        }
        else {
            plus = true;
            for (int i = str.size() - 1; i >= 0; i -= 2) {
                if (i - 1 >= 0)
                    listNumber[k] = symbol_in_numeral(str[i]) + symbol_in_numeral(str[i - 1]) * 10;
                else listNumber[k] = symbol_in_numeral(str[i]);
                k++;
            }
        }
    }
    updatingLength();
}

HugeInt HugeInt::operator-(HugeInt _HugeInt) {
    HugeInt result = HugeInt();
    if (_HugeInt.plus == this->plus) {
        int length_tmp = _HugeInt.length > this->length ? _HugeInt.length : this->length;
        char part_sub = 0;
        int sub;
        char tmp1, tmp2;
        for (int i = 0; i < length_tmp; i++) {
            tmp1 = listNumber[i];
            tmp2 = _HugeInt.listNumber[i];
            sub = ((int)listNumber[i] - (int)_HugeInt.listNumber[i] - (int)part_sub);
            part_sub = 0;
            if (sub < 0) {
                sub += 100;
                part_sub = 1;
            }
            //else if (sub == 0) //
                //part_sub = 1; //
            result.set_listNumber(i, sub);
        }
        if (part_sub != 0) {
            part_sub = 0;
            result.plus = !this->plus;
            for (int i = 0; i < length_tmp; i++) {
                sub = ((int)result.listNumber[i] + (int)part_sub - 100);//
                part_sub = 0;
                if (sub < 0) {
                    sub = abs(sub);
                    part_sub = 1;
                }
                //else if (sub == 0) //
                    //part_sub = 1; //
                result.set_listNumber(i, sub % 100);
            }
        }
        result.updatingLength();
        return result;
    }
    else {
        HugeInt lg1 = HugeInt(_HugeInt);
        HugeInt lg2 = HugeInt(*this);
        lg1.plus = !lg1.plus;
        //HugeInt.plus = !HugeInt.plus;
        return  lg2 + lg1;
    }
}

HugeInt HugeInt::operator+(HugeInt _HugeInt) {
    HugeInt result = HugeInt();
    if (_HugeInt.plus == this->plus) {
        int length_tmp = _HugeInt.length > this->length ? _HugeInt.length : this->length;
        char part_sum = 0;
        char tmp1, tmp2;
        for (int i = 0; i < length_tmp; i++) {
            tmp1 = _HugeInt.listNumber[i];
            tmp2 = listNumber[i];
            result.set_listNumber(i, (_HugeInt.listNumber[i] + listNumber[i] + part_sum) % 100);
            part_sum = (_HugeInt.listNumber[i] + listNumber[i] + part_sum) / 100;
        }
        if (part_sum != 0) {
            result.set_listNumber(length_tmp, part_sum);
        }
        result.plus = plus;
        result.updatingLength();
        return result;
    }
    else {
        if (_HugeInt.plus) {
            //plus = !plus;
            HugeInt lg1 = HugeInt(_HugeInt);
            HugeInt lg2 = HugeInt(*this);
            lg2.plus = !lg2.plus;
            return lg1 - lg2;
        }
        else {
            HugeInt lg1 = HugeInt(_HugeInt);
            HugeInt lg2 = HugeInt(*this);
            lg1.plus = !lg1.plus;
            //HugeInt.plus != HugeInt.plus;
            return  lg2 - lg1;
        }
    }
}

HugeInt HugeInt::operator*(HugeInt _HugeInt) {
    HugeInt result = HugeInt();
    int part_mul;
    int iter = 0;
    HugeInt tmpHugeInt;
    int tmp1, tmp2;
    for (int i = 0; i < _HugeInt.length; i++) {
        part_mul = 0;
        tmpHugeInt = HugeInt();
        for (int j = 0; j < length; j++) {
            tmp1 = _HugeInt.listNumber[i];
            tmp2 = listNumber[j];
            iter = (int)_HugeInt.listNumber[i] * (int)listNumber[j] + (int)part_mul;
            part_mul = iter / 100;
            tmpHugeInt.set_listNumber(j + i, iter % 100);
        }
        if (part_mul != 0) {
            tmpHugeInt.set_listNumber(tmpHugeInt.length, part_mul);
        }
        result = result + tmpHugeInt;
    }
    if (_HugeInt.plus != plus)
        result.plus = false;
    result.updatingLength();
    return result;
}

HugeInt::HugeInt(string str) {
    plus = true;
    maxLength = 10;
    listNumber = new char[maxLength];
    length = 0;
    setNumber(str);
}

HugeInt::HugeInt() {
    plus = true;
    maxLength = 10;
    listNumber = new char[maxLength];
    length = 0;
    for (int i = length; i < maxLength; i++)
        listNumber[i] = 0;
}

HugeInt::HugeInt(const HugeInt &lg) {
    plus = lg.plus;
    maxLength = lg.maxLength;
    listNumber = new char[maxLength];
    length = lg.length;
    for (int i = 0; i < maxLength; i++)
        if (i < lg.length){
            listNumber[i] = lg.listNumber[i];
        }
        else{
            listNumber[i] = 0;
        }
}

HugeInt::~HugeInt() {
    //delete[] listNumber;
}

主.cpp:

#include "stdafx.h"
#include "HugeInt.h"

int _tmain(int argc, _TCHAR* argv[])
{
    /*
    string num1, num2;

    cout << "Enter the first number:" << endl;
    cin >> num1;
    cout << "Enter the second number:" << endl;
    cin >> num2;

    HugeInt hugeNum1 = HugeInt(num1);
    HugeInt hugeNum2 = HugeInt(num2);

    cout << "Entered the following numbers:" << endl;
    cout << "First number: " << num1 << endl;
    cout << "Second number: " << num2 << endl;

    HugeInt sum = hugeNum1 + hugeNum2;
    HugeInt sub = hugeNum1 - hugeNum2;
    HugeInt mul = hugeNum1 * hugeNum2;

    cout << "Summary = " << sum.toString() << endl;
    cout << "Substruction = " << sub.toString() << endl;
    cout << "Multiplacation = " << mul.toString() << endl;
    */

    HugeInt longNumber1;
    HugeInt longNumber2;
    HugeInt longNumberRes;
    /*
    int firstTrue = 1837;
    int secondTrue = -8108;
    char buf[32];
    itoa(firstTrue, buf, 10);
    string firststr(buf);
    itoa(secondTrue, buf, 10);
    string secstr(buf);

    longNumber1.setNumber(firststr);
    longNumber2.setNumber(secstr);

    longNumberRes = longNumber1 + longNumber2;
    int res = atoi(longNumberRes.toString().c_str());

        cout << "Good " << firstTrue << "+" << secondTrue << "=" << res << endl;

        int firstFalse = 312;
        int secondFalse = 712;
        char buf2[32];
        itoa(firstFalse, buf2, 10);
        string firststr2(buf2);
        itoa(secondFalse, buf2, 10);
        string secstr2(buf2);

        longNumber1.setNumber(firststr2);
        longNumber2.setNumber(secstr2);

        longNumberRes = longNumber1 - longNumber2;
        int res2 = atoi(longNumberRes.toString().c_str());

        cout << "Bad " << firstFalse << "-" << secondFalse << "=" << res2 << endl;

        */

    for (int i = 0; i < 1000; i++)
    {
        int first = rand() % 20000 - 10000;
        int second = rand() % 20000 - 10000;
        char buf[32];
        itoa(first, buf, 10);
        string firststr(buf);
        itoa(second, buf, 10);
        string secstr(buf);

        longNumber1.setNumber(firststr);
        longNumber2.setNumber(secstr);

        longNumberRes = longNumber1 - longNumber2;
        int res = atoi(longNumberRes.toString().c_str());
        if (res != first - second)
            cout << i << " = "<< first << "+" << second << "=" << res << endl;
    }
    system("pause");
    return 0;
}

当我使用 1000 个随机数进行测试时,它会打印以下结果(1000 个结果中有 5 个不正确):

48 = 6118+-7918=-1700
268 = -8887+4887=-3900
326 = 3169+-6169=-2900
474 = 212+-712=-400
492 = 1333+-7133=-5700
545 = 8352+-9552=-1100
617 = -4395+195=-4100

减号操作看起来有问题,但我不明白到底是什么。请帮忙,实施中有什么问题以及如何解决?

在此处输入图像描述

标签: c++classlong-integerarithmetic-expressions

解决方案


推荐阅读