模拟大数据的基本计算, 以解决常规计算器计算数据时位数的有限性

项目名称 大数计算器

*************************************************

大数计算的底层采用string对象存储, 将整型数据转换为字符型进行存储运算的加减;采用逐位进行加减, 设计标记位, 标记进位与借位的方式;乘除在加减的基础上控制循环的次数完成对数据的处理

#include<iostream>
#include<cassert>
#include<string.h>
#include<string>
using namespace std;
#define INT_64 long long
#define UN_INIT  0xcccccccccccccccc//不能分开
#define MIN_INT  0xffffffffffffffff
#define MAX_INT  (unsigned)0x7fffffffffffffff
class  BigData
{
public:
    BigData()
        :_data(0)
        , _pdata("")
    {}
    BigData(INT_64 data)
        :_data(data)
    {
        INT_64 tmp = _data;
        char cSymbol = '+';
        if (tmp<0)
        {
            tmp = 0 - tmp;
            cSymbol = '-';
        }
        _pdata.append(1, cSymbol);
        while (tmp)
        {
            _pdata.append(1, tmp % 10 + '0');
            tmp /= 10;
        }
        char* left = (char*)(_pdata.c_str() + 1);
        char* right = (char*)(_pdata.c_str() + _pdata.size() - 1);
        char temp;
        while (left < right)
        {
            temp = *left;
            *left++ = *right;
            *right-- = temp;
        }
        cout<<_data<<_pdata<<endl;
    }
    BigData(const char* pData)
    {
        assert(pData);
        INT_64 ret = 0;
        char* source = (char*)pData;
        char cSymbol = '+';
        if (*source == '-' || *source == '+')
            cSymbol = *source++;
        //while (*source == '0')
            //source++;
        _pdata.append(1, cSymbol);
        while (*source <= '9'&&*source >= '0')
        {
            if (ret <= MAX_INT)
                ret = ret * 10 + *source-'0';
            _pdata.append(1, *source);
            source++;
        }
        if (*source = '-')
            ret = 0 - ret;
        _data = ret;
    }
    BigData(const BigData& bigData)
    {
        _data = bigData._data;
        _pdata = bigData._pdata;
    }
    BigData operator+(BigData& bigData)
    {
        if (!IsINT64OverFlow() && !bigData.IsINT64OverFlow())
        {
            if (_pdata[0] != bigData._pdata[0])
                return BigData(_data + bigData._data);
            else
            {
                if ('+' == _pdata[0] && MAX_INT - _data <= bigData._data || '-' == _pdata[0] && _data >= MIN_INT - bigData._data)
                    return  BigData(_data + bigData._data);
            }
        }
        return BigData(Add(_pdata, bigData._pdata).c_str());
    }
    BigData operator-(BigData& bigData)
    {
        if (!IsINT64OverFlow() && !bigData.IsINT64OverFlow())
        {
            if (_pdata[0] == bigData._pdata[0])
                return BigData(_data - bigData._data);
            else
            {
                if ('+' == _pdata[0] && _data <= MAX_INT + bigData._data || '-' == _pdata[0] && _data >= MIN_INT + bigData._data)
                    return  BigData(_data - bigData._data);
            }
        }
        string ret;
        if (_pdata[0] == bigData._pdata[0])
            ret = Sub(_pdata, bigData._pdata);
        else
        {
            ret = Add(_pdata, bigData._pdata);
            ret[0] = _pdata[0];
        }
        return BigData(ret.c_str());
    }
    BigData operator*(BigData& bigData)
    {
        if (!IsINT64OverFlow() && !bigData.IsINT64OverFlow())
        {
        	cout<<"pppp";
            if (_pdata[0] == bigData._pdata[0])
            {
                if ('+' == _pdata[0] && _data <= (MAX_INT / bigData._data )|| '-' == _pdata[0] && _data >= MAX_INT / bigData._data)
                {
    cout<<(_data*bigData._data)<<"KKKKK";
return  BigData(_data *bigData._data);
    
}
            }
            else
            {
                if ('+' == _pdata[0] && _data <= MIN_INT / bigData._data || '-' == _pdata[0] && _data >= MIN_INT / bigData._data)
                    return  BigData(_data * bigData._data);
            }
        }
       cout<<"KKKKKKKKll";
    return BigData(Mul(_pdata, bigData._pdata).c_str());
    }
    BigData operator/(BigData& bigData)
    {
        if (_data == 0 || bigData._data == 0)
            return BigData((INT_64)0);
        if (!IsINT64OverFlow() && !bigData.IsINT64OverFlow())
        {
            return BigData(_data / bigData._data);
        }
        return  BigData(Div(_pdata, bigData._pdata).c_str());
    }
    friend  ostream& operator<<(ostream& out, const BigData& b)
    {
        out << b._pdata;
        return out;
    }
    friend  istream& operator>>(istream& in, BigData& b)
    {
        in >> b._pdata;
        return in;
    }
protected:
    bool  IsINT64OverFlow()
    {
        if (_data <= MAX_INT&&_data >= MIN_INT)
       {
       		cout<<"normal"<<endl;
    	return false;
}
cout<<"haha"<<endl;
        return true;
    }
    string Add(string s1, string s2)
    {
        int leftSize = s1.size();
        int rightSize = s2.size();
        string ret;
        char cSymbol = '+';
        if (s1[0] == s2[0])
        {
            if (s1[0] == '-')
                cSymbol = '-';
        }
        else
        {
            if (s1[0] == '+'&&strcmp(s1.c_str() + 1, s2.c_str() + 1) < 0 || s1[0] == '-'&&strcmp(s1.c_str() + 1, s2.c_str() + 1)>0)
                cSymbol = '-';
        }
        if (leftSize < rightSize)
        {
            swap(s1, s2);
            swap(leftSize, rightSize);
        }
        ret.resize(leftSize + 1);
        ret[0] = cSymbol;
        char cRes, cStep = 0;
        for (int idx = 1; idx < leftSize; ++idx)
        {
            cRes = s1[leftSize - idx] - '0' + cStep;
            if (idx<rightSize)
                cRes += (s2[rightSize - idx] - '0');
            cStep = cRes / 10;
            ret[leftSize - idx + 1] = cRes % 10 + '0';
        }
        ret[1] = cStep + '0';
        return ret;
    }
    string Sub(string s1, string s2)
    {
        int leftSize = s1.size();
        int rightSize = s2.size();
        char cSymbol = s1[0];
        //leftSize == rightSize &&(cSymbol == '+'&&strcmp(s1.c_str() + 1, s2.c_str() + 1) < 0 || cSymbol == '-'&&strcmp(s1.c_str() + 1, s2.c_str() + 1) > 0)
        if (leftSize < rightSize || leftSize == rightSize &&strcmp(s1.c_str() + 1, s2.c_str() + 1) < 0)
        {
            swap(s1, s2);
            swap(leftSize, rightSize);
            if ('+' == cSymbol)
                cSymbol = '-';
            else
                cSymbol = '+';
        }
        string ret;
        ret.resize(leftSize);
        ret[0] = cSymbol;
        char cRet;
        for (int idx = 1; idx < leftSize; ++idx)
        {
            cRet = s1[leftSize - idx] - '0';
            if (idx < rightSize)
                cRet -= (s2[rightSize - idx] - '0');
 
            if (cRet < 0)
            {
                s1[leftSize - idx - 1] -= 1;
                cRet += 10;
            }
            ret[leftSize - idx] = cRet + '0';
        }
        return ret;
    }
    string Mul(string s1, string s2)
    {
        int leftSize = s1.size();
        int rightSize = s2.size();
        if (leftSize < rightSize)
        {
            swap(leftSize, rightSize);
            swap(s1, s2);
        }
        char cSymbol = '+';
        if (s1[0] != s2[0])
            cSymbol = '-';
        string ret;
        ret.resize(leftSize + rightSize - 1);
        memset((void*)ret.c_str(),'0',ret.size()*sizeof(char));
        ret[0] = cSymbol;
        int iDataLen = ret.size();
        int offSet = 0;
        for (int idx = 1; idx < rightSize; ++idx)
        {
            char cLeft = s2[rightSize - idx] - '0';
            char cStep = 0;
            if (cLeft == 0)
            {
                ++offSet;
                continue;
            }
            for (int iLdx = 1; iLdx < leftSize; ++iLdx)
            {
                char cRet = cLeft*(s1[leftSize - iLdx] - '0');
                cRet += (cStep + ret[iDataLen - iLdx - offSet] - '0');
                ret[iDataLen - iLdx - offSet] = cRet % 10 + '0';
                cStep = cRet / 10;
            }
            ret[iDataLen - offSet - leftSize] += cStep;
            ++offSet;
        }
        //cout<<ret;
        return ret;
    }
    string Div(string s1, string s2)
    {
        int leftSize = s1.size();
        int rightSize = s2.size();
        char cSymbol = '+';
        if (s1[0] != s2[0])
        {
            cSymbol = '-';
        }
        if (leftSize < rightSize || (leftSize == rightSize&&strcmp(s1.c_str() + 1, s2.c_str() + 1)))
        {
            return "0";
        }
        else
        {
            if ("1" == s2 || "-1" == s2)
            {
                s1[0] = cSymbol;
                return s1;
            }
        }
        char *left = (char*)(s1.c_str() + 1);
        left[leftSize-1]='/0';
char* right = (char*)(s2.c_str() + 1);
right[rightSize-1]='/0';
        int iDataLen = rightSize-1;
        string ret;
        ret[0]=cSymbol;
        int idx;
        for (idx = 0; idx < leftSize-1;++idx)
        {
        	cout<<"idx"<<left<<endl;
            if (!IsLeftStrRight(left, iDataLen, right, rightSize - 1))
            {
                iDataLen++;
                ret.append(1, '0');
                continue;
            }
            else
            {
            	cout<<"SubLoop"<<left<<endl;
                ret.append(1, SubLoop(left, iDataLen, right, rightSize - 1));
                cout<<"after"<<left<<endl;
                iDataLen+=rightSize-1;
            }
        }
        return ret;
    }
    char SubLoop(char*& left, int& lSize, char* right, int rSize)
    {
         assert(left&&right);
        char cRet = '0';
        //int srcLeft=lSize;
        while (1)
        {
            if (!IsLeftStrRight(left, lSize, right, rSize))
            {
            	cout<<"false:"<<cRet<<"left"<<left<<endl;
            	break;
}    
cout<<"while"<<left<<"cRet"<<cRet<<endl;
            int lDataLen = lSize-1;
            int rDataLen = rSize-1;
            while (lDataLen >= 0 && rDataLen >= 0)
            {
                if (left[lDataLen] < right[rDataLen])
                {
                	if(lDataLen<1)
                    	break;
                    left[lDataLen - 1] -= 1;
                    left[lDataLen] += 10;
                }
                left[lDataLen] -= right[rDataLen];
                left[lDataLen]+='0';
                lDataLen--;
                rDataLen--;
            }
            cout<<left<<endl;
            while ('0' == *left)
            {
                left++;
                lSize--;
            }
            cRet++;
        }
        return cRet;
    }
    bool  IsLeftStrRight(char* left, int lSize, char* right, const int rSize)
    {
        assert(left&&right);
        if (lSize>rSize || lSize == rSize&&strncmp(left, right, lSize) >= 0)
            return true;
        return false;
    }
private:
    INT_64 _data;
    string _pdata;
};
int main()
{
 //   BigData b1(102);
   // BigData b2(3);
    //BigData  b3= b1 /b2;
    //cout << b3 << endl;
    cout<<(123<=(signed)0x7fffffffffffffff)<<endl;
}

原创文章,作者:carmelaweatherly,如若转载,请注明出处:https://blog.ytso.com/192039.html

(0)
上一篇 2021年11月14日
下一篇 2021年11月14日

相关推荐

发表回复

登录后才能评论