大数运算

自己写的大数运算,目前只写了加减乘三个操作。负数、小数、除法还在研究当中。。。


#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define DEFAULT_BUFF_SIZE 3000
#define SECURITY_BUFF_SIZE 8

using namespace std;

//Kiritow's General class BigNumber. Written on Nov. 14th, 2015
//BigNumber Build 1
//All rights reserved. Nobody is allowed to copy without permission.
class bign
{
private:
    int* data;
    int data_max;
public:
    bign()
    {
        try
        {
            data=new int[DEFAULT_BUFF_SIZE];
            data_max=DEFAULT_BUFF_SIZE;
            set_empty();
        }
        catch(...)
        {
            cerr<<"Class BIGN : "<<(void*)this<<" : Cannot get enough memory"<<endl;
            data_max=0;
            data=nullptr;
        }
    }
    bign(const bign& inc)
    {
        data_max=inc.data_max;
        try
        {
            data=new int[data_max];
            set_empty();
            memcpy(data,inc.data,sizeof(int)*data_max);
        }
        catch(...)
        {
            cerr<<"Class BIGN : "<<(void*)this<<" : Cannot get enough memory"<<endl;
            data_max=0;
            data=nullptr;
        }
    }
    bign(long inc)
    {
        char buff[32];
        try
        {
            //This is a BIG try module, which is not recommend.
            //But here we have to write it like this as we don't want any exceptions thrown in constructor
            //and we don't know which type to return.
            data=new int[DEFAULT_BUFF_SIZE];
            data_max=DEFAULT_BUFF_SIZE;
            set_empty();
            memset(buff,0,32);
            sprintf(buff,"%ld",inc);
            int len=strlen(buff);
            for(int i=len-1;i>=0;i--)
            {
                data[len-1-i]=buff[i]-'0';
            }
        }
        catch(...)
        {
            cerr<<"Class BIGN : "<<(void*)this<<" : Cannot get enough memory"<<endl;
            data=nullptr;
            data_max=0;
        }
    }
    bign(const char* inc)
    {
        int len=strlen(inc);
        data=nullptr;
        if(len>DEFAULT_BUFF_SIZE)
        {
            data_max=len+SECURITY_BUFF_SIZE;
        }
        else
        {
            data_max=DEFAULT_BUFF_SIZE;
        }
        reset_buff_size(data_max);
        if(data!=nullptr)
        {
            for(int i=len-1; i>=0; i--)
            {
                data[len-1-i]=inc[i]-'0';
            }
        }
    }
    ~bign()
    {
        if(data!=nullptr)
        {
            delete[] data;
        }
    }
    char* convert_to_str(char* str)
    {
        int lenx=len();
        for(int i=lenx-1;i>=0;i--)
        {
            str[lenx-i-1]=data[i]+'0';
        }
        return str;
    }
    bool can_be_converted_to_long()
    {
        int thislen=len();
        if(thislen<10)
        {
            return true;
        }
        else if (thislen==10)
        {
            bign tmp(2147438647);
            return *this<tmp;
        }
        else
        {
            return false;
        }
    }
    operator long() throw(const char*)
    {
        if(can_be_converted_to_long())
        {
            char buff[32];
            memset(buff,0,32);
            int length=len();
            for(int i=0;i<length;i++)
            {
                buff[length-i-1]=data[i];
            }
            long tmp;
            sscanf(buff,"%ld",&tmp);
            return tmp;
        }
        else
        {
            throw "BIGN::operator long int() : cannot convert to type long";
        }
    }
    void set_empty()
    {
        memset(data,0,sizeof(int)*data_max);
    }
    int len() const
    {
        for(int i=data_max-1;i>=0;i--)
        {
            if(data[i]!=0)
            {
                return i+1;
            }
        }
        return 0;
    }
    int reset_buff_size(int NewBuffSize)
    {
        if(data!=nullptr) delete[] data;
        try
        {
            data=new int[NewBuffSize];
            data_max=NewBuffSize;
            set_empty();
        }
        catch(...)
        {
            data=nullptr;
            data_max=0;
            cerr<<"Class BIGN : "<<(void*)this<<" : Cannot get enough memory"<<endl;
            return -1;
        }
        return 0;
    }
    bool operator < (const bign& inc) const
    {
        if(this==&inc) return false;
        int lena=len();
        int lenb=inc.len();
        if(lena<lenb)
        {
            return true;
        }
        else if(lenb>lena)
        {
            return false;
        }
        else
        {
            for(int i=lena-1;i>=0;i--)
            {
                if(data[i]<inc.data[i])
                {
                    return true;
                }
                else if(data[i]>inc.data[i])
                {
                    return false;
                }
            }
            return false;
        }
    }
    bool operator > (const bign& inc) const
    {
        if(this==&inc) return false;
        int lena=len();
        int lenb=inc.len();
        if(lena<lenb)
        {
            return false;
        }
        else if(lenb>lena)
        {
            return true;
        }
        else
        {
            for(int i=lena-1;i>=0;i--)
            {
                if(data[i]<inc.data[i])
                {
                    return false;
                }
                else if(data[i]>inc.data[i])
                {
                    return true;
                }
            }
            return false;
        }
    }
    bool operator == (const bign& inc) const
    {
        if(this==&inc) return true;
        int lena=len();
        int lenb=inc.len();
        if(lena!=lenb)
        {
            return false;
        }
        else
        {
            for(int i=lena-1;i>=0;i--)
            {
                if(data[i]!=inc.data[i])
                {
                    return false;
                }
            }
            return true;
        }
    }
    bool operator >= (const bign& inc) const
    {
        return (*this>inc)&&(*this==inc);
    }
    bool operator <= (const bign& inc) const
    {
        return (*this<inc)&&(*this==inc);
    }
    bign& operator = (const bign& inc)
    {
        if(this==&inc) return *this;
        if(inc.data_max>data_max)
        {
            reset_buff_size(inc.data_max);
        }
        for(int i=0;i<inc.data_max;i++)
        {
            data[i]=inc.data[i];
        }
        return *this;
    }
    friend bign operator + (const bign& a,const bign& b);
    friend bign operator - (const bign& a,const bign& b);
    friend bign operator * (const bign& a,const bign& b);
};

bign operator + (const bign& a ,const bign& b)
{
    bign tmp;
    int maxsize=(a.data_max>b.data_max)?(a.data_max):(b.data_max);
    if(maxsize>tmp.data_max)
    {
        tmp.reset_buff_size(maxsize);
    }
    int maxlen=(a.len()>b.len())?(a.len()):(b.len());
    for(int i=0;i<maxlen;i++)
    {
        tmp.data[i]+=a.data[i]+b.data[i];
        if(tmp.data[i]>9)
        {
            tmp.data[i]-=10;
            tmp.data[i+1]++;
        }
    }
    return tmp;
}

bign operator - (const bign& a,const bign& b)
{
    bign tmp;
    int maxsize=(a.data_max>b.data_max)?(a.data_max):(b.data_max);
    if(maxsize>tmp.data_max)
    {
        tmp.reset_buff_size(maxsize);
    }
    int maxlen=(a.len()>b.len())?(a.len()):(b.len());
    if(a>b)
    {
        for(int i=0;i<maxlen;i++)
        {
            tmp.data[i]+=a.data[i]-b.data[i];
            if(tmp.data[i]<0)
            {
                tmp.data[i]+=10;
                tmp.data[i+1]--;
            }
        }
    }
    else if(a<b)
    {
        for(int i=0;i<maxlen;i++)
        {
            tmp.data[i]+=b.data[i]-a.data[i];
            if(tmp.data[i]<0)
            {
                tmp.data[i]+=10;
                tmp.data[i+1]--;
            }
        }
    }
    return tmp;
}

bign operator * (const bign& a,const bign& b)
{
    bign tmp;
    int lena=a.len();
    int lenb=b.len();
    if(tmp.data_max<lena+lenb+1)
    {
        tmp.reset_buff_size(lena+lenb+1);
    }
    for(int i=0;i<lena;i++)
    {
        for(int j=0;j<lenb;j++)
        {
            tmp.data[i+j]+=a.data[i]*b.data[j];
        }
    }
    for(int i=0;i<tmp.data_max-1;i++)
    {
        if(tmp.data[i]>9)
        {
            tmp.data[i+1]+=tmp.data[i]/10;
            tmp.data[i]=tmp.data[i]%10;
        }
    }
    return tmp;
}

char buff[3000];
int main()
{
    bign a("1234"),b("5678");
    a=a+b;
    printf("%s\n",a.convert_to_str(buff));
    return 0;
}


在写的时候参考了一下string的设计,之前operator都是以成员函数重载的,所以这样的操作

bign a,b;
a+b;

a+b的时候就会直接把结果存入a中,然而并不一定符合本意。

所以就改成了友元函数,并且返回值而不是引用。



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值