C++大整数类

实现了 + - * ,除法还没有完成。
利用string类模拟手工加减乘。

头文件

#pragma once
#include <string>
#include <iostream>
using namespace std;

typedef long long INT64;

class BigData {
public:
    friend ostream& operator << (ostream& cout, BigData);
    BigData();
    BigData(const string& _strData);
    string Mul(string strLeft, string strRight);
    string Sub(string strLeft, string strRight);
    string Add(string strLeft, string strRight);
    BigData operator*(const BigData& bg);
    BigData operator-(const BigData& bg);
    BigData operator+(const BigData& bg);
private:
    string _strData;
};
#include "BigData.h"
#include <algorithm>
BigData::BigData()
    : _strData("")
{
}
BigData::BigData(const std::string& str)
    : _strData(str)
{
}
BigData BigData::operator-(const BigData& bg)
{
    BigData tmp;
    tmp._strData = Sub(this->_strData, bg._strData);
    return tmp;
}

BigData BigData::operator+(const BigData& bg)
{
    BigData tmp;
    tmp._strData = Add(this->_strData, bg._strData);
    return tmp;
}

string _Add(std::string strLeft, std::string strRight);
string BigData::Add(std::string strLeft, std::string strRight)
{
    if (strLeft[0] == strRight[0]) {
        return _Add(strLeft, strRight);
    }
    else {
        //异号相加变为同号相减
        if (strLeft[0] == '-') {
            strLeft[0] = '+';
            strLeft.swap(strRight);
        }
        else {
            strRight[0] = '+';
        }
        return BigData::Sub(strLeft, strRight);
    }
}
string _Add(std::string strLeft, std::string strRight)
{
    int sizeLeft = strLeft.size();
    int sizeRight = strRight.size();
    if (sizeLeft < sizeRight) {
        strLeft.swap(strRight);
        swap(sizeLeft, sizeRight);
    }
    string strRet(sizeLeft +1 , '0');
    strRet[0] = strLeft[0];
    int idxL = sizeLeft - 1; 
    int idxR = sizeRight - 1;
    for (; idxL >0; idxL--, idxR--) {
        int c = strLeft[idxL] - '0';
        if (idxR >= 1) {
            c = c + strRight[idxR] - '0';
        }
        if (c > 9) {
            strLeft[idxL - 1] += 1;
            c -= 10;
        }
        strRet[idxL+1] = c + '0';
    }
    return strRet;
}
string _Sub(std::string strLeft, std::string strRight);
string BigData::Sub(std::string strLeft, std::string strRight)
{
    if (strLeft[0] == strRight[0]) {
        //如果为负-负,变为正-正的形式
        if (strLeft[0] == '-') {
            strRight[0] = '+';
            strLeft[0] = '+';
            strLeft.swap(strRight);
        }
        return _Sub(strLeft, strRight);
    }
    else {
        //异号相减,变成同号相加
        if (strRight[0] == '-') {
            strRight[0] = '+';
        }
        else {
            strRight[0] = '-';
        }
        return BigData::Add(strLeft, strRight);
    }
}
//同号
string _Sub(std::string strLeft, std::string strRight) {
    //有没有超出范围
    int LSize = strLeft.size();
    int RSize = strRight.size();
    //调整被减数顺序
    char symbol = '+';
    if (LSize < RSize || LSize == RSize && strLeft < strRight) {
        strLeft.swap(strRight);
        swap(LSize, RSize);
        symbol = '-';
    }
    std::string strRet(LSize, '0');
    strRet[0] = symbol;
    //取最低位相减
    for (int idxL = LSize - 1, idxR = RSize - 1; idxL > 0; idxL--, idxR--) {
        char c = strLeft[idxL] - '0';
        if (idxR >= 1) {
            c = c - (strRight[idxR] - '0');
        }
        if (c < 0) {
            strLeft[idxL - 1] -= 1;//借位
            c += 10;
        }
        strRet[idxL] = c + '0';
    }
    return strRet;
}
ostream& operator << (ostream& cout, BigData bg)
{
    cout <<bg._strData;
    return cout;
}

BigData BigData::operator*(const BigData& bg)
{
    /*
    检测合法性,比较麻烦
    if (IsINT64Overflow() && bg.IsINT64Overflow()) {
        if (0 == _value) {
            return BigData("+0");
        }
        //同号相乘
        if (_strData[0] == bg._strData[0]) {
            //乘完的结果是否合法
            if (('+' == _strData[0] && maxValue / _value >= bg._value)
                ||('-' == _strData[0] && maxValue / _value <= bg._value)) {
                return BigData(_value / bg._value);
            }
        }
    }
    else {
        //异号
        if (0 == _value) {
            return BigData("+0");
        }
        if (_strData[0] == bg._strData[0]) {
            //乘完的结果是否合法
            //-10 / 2 = -5   <= -3
            if (('+' == _strData[0] && minValue / _value <= bg._value)
                || ('-' == _strData[0] && minValue / _value >= bg._value)) {
                return BigData(_value / bg._value);
            }
        }
    }
    */

    return BigData(Mul(_strData, bg._strData));
}


string BigData::Mul(string strLeft, string strRight) {
    //模拟过程,每次取右操作数一位和左数相乘,临时结果ret
    char symbol = '+';
    if (strLeft[0] != strRight[0]) {
        symbol = '-';
    }
    int LSize = strLeft.size();
    int RSize = strRight.size();
    if (LSize > RSize) {
        swap(strLeft, strRight);
        swap(LSize, RSize);
    }
    //结果最多位数
    std::string strRet(LSize + RSize - 1, '0');
    strRet[0] = symbol;
    int offset = 0;
    for (int idxL = LSize - 1; idxL > 0; idxL--) {
        //进位清零
        char cStep = 0;
        //取左操作数当前位
        char cLeft = strLeft[idxL] - '0';
        //用cLeft乘右操作数每一位
        for (int idxR = RSize - 1; idxR > 0; idxR--) {
            char cRet = cLeft * (strRight[idxR] - '0') + cStep;
            //偏移后需要加上原来的位的数据
            cRet += strRet[LSize + idxR - 1 - offset] - '0';
            cStep = cRet / 10;
            cRet = cRet % 10;
            //保存结果的最低位
            strRet[LSize + idxR -1 - offset] = cRet + '0';
        }
        strRet[LSize - 1 - offset] = cStep + '0';
        offset++;
    }
    return strRet;
}

/*除法思路
确定每次除的位数,如果被除数大于除数,结果补零除数增加一位。具体除法用循环相减。
*/

测试用例

#include "BigData.h"
#include <iostream>
using namespace std;
int main() {
    BigData bg1("+10005");
    BigData bg2("-3216");
    cout << bg1 + bg1 << endl << bg2 + bg2 << endl << bg1 - bg1 << endl << bg2 - bg2 << endl;
    cout << bg1 + bg2 << endl << bg2 + bg1 << endl << bg1 - bg2 << endl << bg2 - bg1 << endl;
    BigData bg3("+199");
    BigData bg4("+9999");
    cout << bg3*bg4;

}

猜你喜欢

转载自blog.csdn.net/hanzheng6602/article/details/80839582