自己写的大数运算,目前只写了加减乘三个操作。负数、小数、除法还在研究当中。。。
#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;
所以就改成了友元函数,并且返回值而不是引用。