C++ Class版大數

可處理 + - * with負數

/*  Date: 2009.06.14  */
/*  BigInt + - * with Negative version */ 

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

class BigInt
{
    public:
        static const int size = 100;
        bool sign;
        BigInt();
        BigInt(const char *n);
        BigInt invert() const;
        friend ostream& operator << (ostream& os, BigInt t);
        friend bool operator > (const BigInt& tl, const BigInt& tr);    
        friend bool operator < (const BigInt& tl, const BigInt& tr);    
        friend BigInt operator + (const BigInt& tl, const BigInt& tr);
        friend BigInt operator += (BigInt& tl, const BigInt& tr);
        friend BigInt operator - (const BigInt& tl, const BigInt& tr);
        friend BigInt operator * (const BigInt& tl, const BigInt& tr);        
        
    private:
        void initialize();    
        int num[size];
        int len;
};
void BigInt::initialize()
{
    sign = true;
    len = 1;
    memset(num, 0sizeof(num));    // fill num with 0
}
BigInt::BigInt()
{
    initialize();
}
BigInt::BigInt(const char *n)
{
    initialize();
    int check = 0;
    if(n[0] == '-')    // check if it is negative
    {
        sign = false;
        check++;
    }
    else if(n[0] == '+'// eliminate + symbol
        check++;
    len = strlen(n);

    for(int i=check; i<len ;i++)
    {
        if(n[i] == '0')
            check++;
        else
            break;
    }
    for(int i=len-1, j=0; i>=check; i--, j++)
    {
        num[j] = n[i] - '0';    // turn it to int
    }
    len -= check;
    if(len == 0)    // if empty
    {
        num[0] = 0;
        len = 1;    
    }
}
BigInt BigInt::invert() const    // return its invert sign num    
{
    BigInt tmp(*this);
    tmp.sign = !tmp.sign;
    return tmp;    
}
ostream& operator << (ostream& os, BigInt t)
{
    char tmp[BigInt::size];
    int len = 0;
    if(t.sign == false)
    {
        tmp[0] = '-';
        len++;
    }
    for(int i=t.len-1; i>=0; i--)
    {
        tmp[len] = t.num[i] + '0';    
        len++;
    }
    tmp[len] = '\0';
    os << tmp;
    return os;
}
bool operator > (const BigInt& tl, const BigInt& tr)
{
    if(tl.sign == true && tr.sign == true)
    {
        if(tl.len > tr.len) return true;
        else if(tl.len < tr.len) return false;
        else
        {
            for(int i=tl.len-1; i>=0; i--)
            {
                if(tl.num[i] > tr.num[i]) return true;
                else if(tl.num[i] < tr.num[i]) return false;
                else continue;    
            }
            return false;
        }    
    }
    else if(tl.sign == true && tr.sign == false)
        return true;
    else if(tl.sign == false && tr.sign == true)
        return false;
    else if(tl.sign == false && tr.sign == false)
    {
        return tr.invert() > tl.invert();    
    }
}
bool operator < (const BigInt& tl, const BigInt& tr)
{
    return (tr > tl);    
}

BigInt operator + (const BigInt& tl, const BigInt& tr)
{
    BigInt ans;
    if(tl.sign == false && tr.sign == true)
    {
        return tr - tl.invert();    
    }
    else if(tl.sign == true && tr.sign == false)
    {
        return tl - tr.invert();    
    }
    else if(tl.sign == false && tr.sign == false)
    {
        ans.sign = false;
    }
    ans.len = (tl.len > tr.len) ? tl.len : tr.len;
    for(int i=0; i<ans.len; i++)
    {
        ans.num[i] += tl.num[i] + tr.num[i];    
        if(ans.num[i] >= 10)            // check carry
        {
            ans.num[i + 1] += (ans.num[i] / 10);
            ans.num[i] %= 10;    
        }
    }
    if(ans.num[ans.len] != 0 )
    {
        ans.len++;    
    }
    return ans;
}
BigInt operator += (BigInt& tl, const BigInt& tr)
{
    tl = tl + tr;
    return tl;
}
BigInt operator - (const BigInt& tl, const BigInt& tr)
{
    BigInt ans;
    if(tl.sign == true && tr.sign == false)
    {
        return tl + tr.invert();    
    }    
    else if(tl.sign == false && tr.sign == true)
    {
        return tl + tr.invert();    
    }
    else if(tl.sign == false && tl.sign == false)
    {
        return tr.invert() - tl.invert();
    }
    else
    {
        if(tl < tr)
        {
            ans = tr - tl;
            ans.sign = false;
            return ans;
        }    
        else
        {
            ans.len = tl.len;    
            for(int i=0; i<ans.len; i++)
            {
                if( (ans.num[i] + tl.num[i]) >= tr.num[i] )
                {
                    ans.num[i] += (tl.num[i] - tr.num[i]);
                }    
                else
                {
                    ans.num[i + 1] -= 1;
                    ans.num[i] += 10 + (tl.num[i] - tr.num[i]);
                }
            }
            for(int i=tl.len-1; i>=0; i--, ans.len--)
            {
                if(ans.num[i] != 0)    
                    break;
            }
            if(ans.len == 0)
            {
                ans.len = 1;
                ans.num[0] = 0;
            }
            return ans;
        }
    }
}
BigInt operator * (const BigInt& tl, const BigInt& tr)
{
    BigInt ans;
    ans.sign = !(tl.sign ^ tr.sign);
    ans.len = tl.len + tr.len;
    for(int i=0; i<tl.len; i++)
    {
        for(int j=0; j<tr.len; j++)
        {
            ans.num[i + j] += (tl.num[i] * tr.num[j]);
        }    
    }
    for(int i=0; i<ans.len; i++)
    {
        if(ans.num[i] >= 10)    // check carry
        {
            ans.num[i + 1] += (ans.num[i] / 10);
            ans.num[i] %= 10;    
        }    
    }
    if(ans.num[ans.len - 1] == 0)
    {
        ans.len--;    
    }
    return ans;
}


int main()
{
    char str1[100], str2[100];
    while( cin >> str1 >> str2 )
    {
        BigInt a(str1);
        BigInt b(str2);
        cout << "+ :" << a + b << endl;
        cout << "- :" << a - b << endl;
        cout << "* :" << a * b << endl;
        cout << "< :" << (a < b) << endl;
        cout << "> :" << (a > b) << endl;
        cout << "+=:" << (a += b) << endl;
        cout << a << ", " << b << endl;
    }
    return 0;
}

arrow
arrow
    全站熱搜

    aikosenoo 發表在 痞客邦 留言(4) 人氣()