《C++大数据运算(+、-、*、/)》

来源:互联网 发布:金庸群侠传 武功数据 编辑:程序博客网 时间:2024/05/20 10:11

计算机中整数数据的最大类型为long long类型,依据计算机位数的不同它的范围也不同,以32位为例long long类型的取值范围为【-9223372036854775808,9223372036854775807】,那么计算机可以进行的数值运算就必须在这个范围之内吗?未必,所以产生了大数据运算来解决更大范围内的数值运算,它的思想是以字符串代表数值进行各类运算。
这里写图片描述
Test.c

#include"BigData.h"int main(){    BigData bg1(9900000099);    BigData bg2(33);    BigData bg3;    bg3 = bg1 - bg2;    cout << bg3 << endl;    return 0;}

BigData.h

#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>#include<string>#include<assert.h>#include<ctype.h>using namespace std;typedef long long INT64;const INT64 MAX_VALUE = 9223372036854775807;const INT64 MIN_VALUE = -9223372036854775808;class BigData{public:    BigData(INT64 value = 0);    BigData(const string& str);    BigData operator+(const BigData& bg) const;    BigData operator-(BigData bg) const;    BigData operator*(const BigData& bg) const;    BigData operator/(const BigData& bg) const;    friend ostream& operator<<(ostream& cou,const BigData& bg);    bool IsINT64OverFlow() const;private:    string _strData;    INT64 _value;};

BigData.cpp

#include"BigData.h"BigData::BigData(INT64 value)//用数值初始化对象的构造函数    : _value(value){    char Symbol = '+';    if (value < 0)        Symbol = '-';    do    {        _strData += (value % 10) + '0';        value /= 10;    }    while (value);    _strData += Symbol;    char* ptr = (char*)_strData.c_str();    reverse(ptr, ptr + _strData.size());//逆置字符串}BigData::BigData(const string& str)//用字符串初始化对象的构造函数:_strData("+0"), _value(0){    char* ptr = (char*)str.c_str();    while (isspace(*ptr))//排除空白字符串    {        ptr++;    }    if (*ptr == '\0')        return;    char Symbol = 0;    if (*ptr == '+' || *ptr == '-')    {        Symbol = *ptr;        ptr++;    }    else if (isdigit(*ptr))    {        Symbol = '+';    }    else        return;    while (*ptr == '0')//排除数字最开始处的零        *ptr++;    if (*ptr == '\0')        return;    _strData[0] = Symbol;    int count = 1;    _strData.resize(strlen(ptr) + 1);    while (isdigit(*ptr))    {        _strData[count] = *ptr;        _value = _value*10 + (*ptr - '0');        count++;        ptr++;    }    if (_strData[0] == '-')        _value = -_value;}bool BigData::IsINT64OverFlow() const//判断对象中的_value是否超出long long类型的范围{    string strRet("+9223372036854775807");    if (_strData[0] == '-')        strRet = "-9223372036854775808";    if ((strRet.size() > _strData.size()) || (_strData.size() == strRet.size() && strcmp(_strData.c_str(), strRet.c_str()) <= 0))        return false;    return true;}string Add(string strLeft, string strRight)//同号加法{    string strRet;    size_t LSize = strLeft.size();    size_t RSize = strRight.size();    if (LSize < RSize)//将左参数调整为最长字符串    {        strLeft.swap(strRet);        swap(LSize, RSize);    }    strRet.resize(LSize + 1);//结果字符串最长长度    strRet[0] = strLeft[0];    char Step = 0;//进位    for (size_t i = 1; i < LSize; i++)    {        char Ret = (strLeft[LSize - i] - '0') + Step;        if (i < RSize)            Ret += strRight[RSize - i] - '0';        if (Ret >= 10)        {            Step = Ret / 10;            Ret = Ret % 10;        }        strRet[LSize - i + 1] = Ret + '0';    }    strRet[1] = Step + '0';    return strRet;}string Sub(string strLeft, string strRight)//异号加法{    size_t LSize = strLeft.size();    size_t RSize = strRight.size();    string strRet;//调整左字符串为长度最长或字符串最大的字符(不含符号位)    if (LSize < RSize || (LSize == RSize && strcmp(strLeft.c_str() + 1, strRight.c_str() + 1) < 0))    {        strLeft.swap(strRight);        swap(LSize, RSize);    }    strRet.resize(LSize);    strRet[0] = strLeft[0];    for (size_t i = 1; i < LSize; i++)    {        char Ret = (strLeft[LSize - i] - '0');        if (i < RSize)            Ret -= strRight[RSize - i] - '0';        if (Ret < 0)        {            strRet[LSize - i - 1] -= 1;            Ret += 10;        }        strRet[LSize - i] = Ret + '0';    }    return strRet;}string Mul(string strLeft, string strRight)//乘法{    string strRet;    size_t LSize = strLeft.size();    size_t RSize = strRight.size();    if (LSize > RSize)    {        strLeft.swap(strRight);        swap(LSize, RSize);    }    strRet.resize(LSize + RSize - 1, '0');    if (strLeft[0] == strRight[0])        strRet[0] = '+';    else        strRet[0] = '-';    char offset = 0;    for (size_t i = 1; i < LSize; i++)    {        char Step = 0;        char Ret = strLeft[LSize - i] - '0';//左字符串的从右往左每一位        for (size_t j = 1; j < RSize; j++)//用左字符串取出的一位位乘右字符串的每一位        {            char Res = Ret*(strRight[RSize - j] - '0') + Step                + (strRet[LSize + RSize - 1 - j - offset] - '0');            Step = 0;            if (Res > 10)            {                Step = Res / 10;            }            strRet[LSize + RSize - 1 - j - offset] = (Res % 10) + '0';        }        strRet[LSize - offset - 1] = Step + '0';        offset++;    }    return strRet;}bool IsLeftBig(char* pLeft,size_t DataLen,char* pRight,size_t RSize)//判断除法中每一次进入SubLoop函数中的左参数字符串是否大于右参数字符串{    if (DataLen > RSize ||         (DataLen == RSize && strcmp(pLeft, pRight) >= 0))        return true;    return false;}char SubLoop(char*& pLeft, size_t& DataLen, char*& pRight, size_t& RSize)//除法中的减法{    char Com = '0';//循环次数 == 商数    while (1)    {        while (*pLeft == '0' && DataLen > 0)//最多跳过DataLen个0        {            pLeft++;            DataLen--;        }        if (!IsLeftBig(pLeft, DataLen, pRight, RSize))            break;        for (size_t i = 1; i <= RSize; i++)//一次减法        {            char Ret = pLeft[DataLen - i] - '0';            Ret -= pRight[RSize - i] - '0';            if (Ret < 0)            {                pLeft[DataLen - i - 1] -= 1;                Ret += 10;            }            pLeft[DataLen - i] = Ret + '0';        }        Com++;    }    return Com;}string Div(string strLeft, string strRight)//除法{    string strRet;    char* pLeft = (char*)(strLeft.c_str() + 1);    char* pRight = (char*)(strRight.c_str() + 1);    size_t LSize = strLeft.size();    size_t RSize = strRight.size() - 1;    size_t DataLen = RSize;    if (strLeft[0] == strRight[0])        strRet += '+';    else        strRet += '-';    while (strRet.size() < (LSize - RSize + 1))    {        if (*pLeft == '0')//如果下一位为零,则商零        {            strRet += '0';            pLeft++;            continue;        }        if (!IsLeftBig(pLeft,DataLen,pRight,RSize))        {            strRet += '0';            DataLen++;            strRet += SubLoop(pLeft, DataLen, pRight, RSize);        }        else        {            strRet += SubLoop(pLeft, DataLen, pRight, RSize);        }        DataLen++;    }    return strRet;}BigData BigData::operator+(const BigData& bg) const{    if (!IsINT64OverFlow() && !bg.IsINT64OverFlow())    {        if (_strData[0] != bg._strData[0])        {            return BigData(_value + bg._value);        }        else if ((_strData[0] == '+' && (MAX_VALUE - _value >= bg._value))             || (_strData[0] == '-' && (MIN_VALUE - _value <= bg._value)))        {            return BigData(_value + bg._value);        }    }    if (_strData[0] == bg._strData[0])        return BigData(Add(_strData, bg._strData));    return BigData(Sub(_strData, bg._strData));}BigData BigData::operator-(BigData bg) const{    if (!IsINT64OverFlow() && !bg.IsINT64OverFlow())    {        if (_strData[0] == bg._strData[0])        {            return BigData(_value - bg._value);        }        else if ((_strData[0] == '+' && MAX_VALUE + bg._value >= _value)            || (_strData[0] == '-' && MIN_VALUE + bg._value <= _value))        {            return BigData(_value - bg._value);        }    }    if (_strData[0] == bg._strData[0])    {        if (_strData[0] == '+')            bg._strData[0] = '-';        else            bg._strData[0] = '+';        return BigData(Sub(_strData,bg._strData));    }    else    {        if (_strData[0] == '+')            bg._strData[0] = '+';        else            bg._strData[0] = '-';        return BigData(Add(_strData,bg._strData));    }}BigData BigData::operator*(const BigData& bg) const{    if (_strData == "+0" || bg._strData == "+0")        return BigData(0);    if (!IsINT64OverFlow() && !bg.IsINT64OverFlow())    {        if (_strData[0] == bg._strData[0])        {            if ((_strData[0] == '+' && MAX_VALUE / _value >= bg._value)                || (_strData[0] == '-' && MAX_VALUE / _value <= bg._value))            {                return BigData(_value * bg._value);            }        }        else        {            if ((_strData[0] == '+' && MIN_VALUE / _value <= bg._value)                || (_strData[0] == '-' && MIN_VALUE / _value >= bg._value))            {                return BigData(_value * bg._value);            }        }    }    return BigData(Mul(_strData, bg._strData));}BigData BigData::operator/(const BigData& bg) const{    //除数为0    if (bg._strData == "+0")    {        assert(0);    }    if (_strData == "+0")        return BigData(0);    //左边小于右边    if ((_strData.size() < bg._strData.size())        || ((_strData.size() == bg._strData.size())        && strcmp(_strData.c_str() + 1, bg._strData.c_str() + 1) < 0))        return BigData(0);    if ((_strData.size() == bg._strData.size())        && strcmp(_strData.c_str() + 1, bg._strData.c_str() + 1) == 0)    {        if (_strData[0] == bg._strData[0])            return BigData(1);        else            return BigData(-1);    }    if (bg._strData == "+1" || bg._strData == "-1")    {        BigData tmp(*this);        if (_strData[0] == bg._strData[0])        {            tmp._strData[0] = '+';        }        else        {            tmp._strData[0] = '-';        }        return tmp;    }    if (!IsINT64OverFlow() && !bg.IsINT64OverFlow())        return BigData(_value / bg._value);    return BigData(Div(_strData, bg._strData));}ostream& operator<<(ostream& cou,const BigData& bg){    cou << "string:" << bg._strData << "  value:" << bg._value;    return cou;}
原创粉丝点击