Team Projects/Suggested by Fanta bigint 클래스 수정 지환태 2010. 2. 1. 18:49 #include #include #include #include #include #include #include #pragma warning(disable:4996) class bigint { private: char sign; //+:0, -:1 unsigned *dats; //가장 뒷자리가 dats[0]에 저장 unsigned len; //dats배열 길이 public: unsigned cona2u(char*); bigint(); ~bigint(); bigint(const int); bigint(const unsigned); bigint(const char*); bigint(const bigint &); unsigned resize(unsigned); //길이조절 unsigned resize(); //앞의 0 지우기 bigint abs(); //절대값 bigint negative(unsigned); //1의보수 int cmp(bigint &b); //strcmp와 리턴값 같음 bigint _or(bigint &b); //this에 저장 bigint _and(bigint &b); //this에 저장 bigint _xor(bigint &b); //this에 저장 bigint shr(unsigned n); //this에 (this>>n)을 저장 bigint shl(unsigned n); //this에 (this<>(bigint, bigint); friend bool operator<(bigint, bigint); friend bool operator<=(bigint, bigint); friend bool operator>(bigint, bigint); friend bool operator>=(bigint, bigint); friend bool operator==(bigint, bigint); friend bool operator!=(bigint, bigint); bigint operator|=(bigint); bigint operator&=(bigint); bigint operator^=(bigint); bigint operator+=(bigint); bigint operator-=(bigint); bigint operator*=(bigint); bigint operator/=(bigint); bigint operator%=(bigint); bigint operator<<=(bigint); bigint operator>>=(bigint); bigint operator++(); bigint operator++(int dummy); bigint operator--(); bigint operator--(int dummy); friend std::ostream& operator <<( std::ostream& os, bigint& b ); friend std::istream& operator >>( std::istream& is, bigint& b ); }; unsigned bigint::cona2u(char *src) { unsigned ten, sum, eos=strlen(src)-1; for(sum=0, ten=1; (int)eos>=0 && ten<=100000000; ten*=10, eos--) { sum+=ten*(src[eos]-'0'); src[eos]=0; } return sum; } bigint::bigint() { len=1; sign=0; dats=(unsigned*)calloc(1,sizeof(unsigned)); } bigint::~bigint() { free(dats); } bigint::bigint(const int src) { len=1; dats=(unsigned*)malloc(sizeof(unsigned)*len); if(src<0) { sign=1; dats[0]=-src; } else { sign=0; dats[0]=src; } } bigint::bigint(const char *src) { char *str=(char*)malloc(sizeof(char)*(strlen(src)+1)); sign=0; strcpy(str, src); if(src[0]=='-') strcpy(str,src+1), sign=1; if(src[0]=='+') strcpy(str,src+1); len=(strlen(src)-1)/9 + 1; dats=(unsigned*)malloc(sizeof(unsigned)*len); unsigned i; for(i=0; i=lmt; j--) { if(dats[j]>=2147483648) dats[j]-=1647483648; } } } bigint::bigint(const bigint &src) { len=src.len; sign=src.sign; dats=(unsigned*)malloc(sizeof(unsigned)*len); memcpy(dats, src.dats, sizeof(unsigned)*len); } unsigned bigint::resize(unsigned len_new) { if(len==len_new) return len; unsigned *new_p=(unsigned*)malloc(sizeof(unsigned)*len_new); // memcpy(new_p, dats, sizeof(unsigned)*((lenb.len) return left; if(len=0; i--) { if(dats[i]>b.dats[i]) return left; if(dats[i]>5, cut=n&31, i, j, tmp; dats[0]=dats[move]>>cut; for(i=1; i>cut; } resize(len-move);//옮겨진 부분 삭제 resize(); return *this; } bigint bigint::shl(unsigned n) { unsigned move=n>>5, cut=n&31, i, j, tmp; resize(len+move+1); dats[len-1]=dats[len-move-1]<=(int)move; i--) { for(j=0, tmp=dats[i-move]; j<32-cut; j++) //dats[i+1]=dats[i+1]|(dats[i-move]>>(32-cut)); tmp>>=1; // dats[i+1]=dats[i+1]|tmp; // dats[i]=dats[i-move]<toreturn.len)?b.len:toreturn.len) + 1 ); for(i=0; i>=32; } for(; carry; i++) { carry=(long long)toreturn.dats[i] + carry; toreturn.dats[i]=carry&(((long long)1<<32)-1); carry>>=32; } toreturn.resize(); return toreturn; } //1의 보수 사용 bigint bigint::sub(bigint &b) { bigint toreturn(*this); bigint subtrahend(b); //감수 unsigned len_new=((toreturn.len>b.len)?toreturn.len:b.len); subtrahend=subtrahend.negative(len_new); toreturn=toreturn.add(subtrahend); if(toreturn.len > len_new)//자리올림수있으면 { toreturn.resize(len_new); toreturn=toreturn.add((bigint)1); } else//자리올림수 없으면 { toreturn=toreturn.negative(len_new); toreturn.sign=1; } return toreturn; } bigint bigint::mul(bigint &b) { bigint result, tmp; unsigned i, j; unsigned long long carry; for(i=0; i>=32; } tmp.dats[j+i]=(unsigned)carry; result=result.add(tmp); memset(tmp.dats, 0, sizeof(unsigned)*tmp.len); } result.resize(); return result; } bigint bigint::div(bigint &b, int ask_mod=0) { bigint r=abs(), q=0, divisor=b.abs(), one=1; unsigned i; for(i=0;divisor.cmp(r)<=0;divisor.shl(1),i++); i--; if((int)i>=0) { one.shl(i); divisor.shr(1); while(b.cmp(r)<=0)//b<=r { for(;divisor.cmp(r)>0;divisor.shr(1),one.shr(1)); q._or(one); r=r.sub(divisor); } } if(ask_mod) return r; return q; } std::string bigint::conbcd() { unsigned *bcd, len_new, head, i, j; char str_tmp[10]; std::string result; len_new=10704*len/10000+1+len; bcd=(unsigned*)calloc(len_new, sizeof(unsigned)); memcpy(bcd, dats, sizeof(unsigned)*len); for(head=len, i=0; i<32*len; i++) { for(j=head; j>=len; j--) { if(bcd[j]>=500000000) bcd[j]+=1647483648; } if(bcd[head]>>31) head++; bcd[head]<<=1; for(j=head-1; (int)j>=0; j--) { bcd[j+1]|=(bcd[j]>>31); bcd[j]<<=1; } } for(i=len_new-1; bcd[i]==0; i--); if((int)i<0) { result="0"; return result; } sprintf(str_tmp, "%u", bcd[i]); result.insert(result.size(), str_tmp); for(--i; (int)i>=len; i--) { sprintf(str_tmp, "%09u", bcd[i]); result.insert(result.size(), str_tmp); } free(bcd); return result; } bigint bigint::operator=(const int src) { resize(1); sign=0; dats[0]=src; if(src<0) sign=1, dats[0]*=-1; return *this; } bigint bigint::operator=(const bigint &src) { resize(src.len); sign=src.sign; memcpy(dats, src.dats, sizeof(unsigned)*len); return *this; } bigint bigint::operator=(const char *src) { char *str=(char*)malloc(sizeof(char)*(strlen(src)+1)); sign=0; strcpy(str, src); if(src[0]=='-') strcpy(str,src+1), sign=1; if(src[0]=='+') strcpy(str,src+1); resize((strlen(src)-1)/9 + 1); unsigned i; for(i=0; i=lmt; j--) { if(dats[j]>=2147483648) dats[j]-=1647483648; } } return *this; } bigint operator-(bigint a) { a.sign^=1; return a; } bigint operator|(bigint a, bigint b) { return a._or(b); } bigint operator&(bigint a, bigint b) { return a._and(b); } bigint operator^(bigint a, bigint b) { return a._xor(b); } bigint operator+(bigint a, bigint b) { if(a.sign==b.sign) return a.add(b); if(a.sign==0 && b.sign==1) return a.sub(b); //a.sign==1 && b.sign==0 return b.sub(a); } bigint operator-(bigint a, bigint b) { if(a.sign==1 && b.sign==1) { b.sign=0; if((a.abs()).cmp(b.abs())==1) b.sign=1; b=b.sub(a); return b; } if(a.sign==0 && b.sign==0) return a.sub(b); if(a.sign==0 && b.sign==1) return a.add(b); //a.sign==1 && b.sign==0 a=a.add(b); a.sign=1; return a; } bigint operator*(bigint a, bigint b) { bigint toreturn=a.mul(b); toreturn.sign=a.sign^b.sign; return toreturn; } bigint operator/(bigint a, bigint b) { bigint toreturn=a.abs().div(b.abs()); toreturn.sign=a.sign^b.sign; return toreturn; } bigint operator%(bigint a, bigint b) { bigint toreturn=a.abs().div(b.abs(),1); toreturn.sign=a.sign; return toreturn; } bigint operator<<(bigint a, bigint b) { bigint tmp(2147483647); while(b.len>1) { a.shl(2147483647); b=b.sub(tmp); } a.shl(b.dats[0]); return a; } bigint operator>>(bigint a, bigint b) { bigint tmp(2147483647); while(b.len>1) { a.shr(2147483647); b=b.sub(tmp); } a.shr(b.dats[0]); return a; } bool operator<(bigint a, bigint b) { if(a.cmp(b)<0) return true; return false; } bool operator<=(bigint a, bigint b) { if(a.cmp(b)<=0) return true; return false; } bool operator>(bigint a, bigint b) { if(a.cmp(b)>0) return true; return false; } bool operator>=(bigint a, bigint b) { if(a.cmp(b)>=0) return true; return false; } bool operator==(bigint a, bigint b) { if(a.cmp(b)==0) return true; return false; } bool operator!=(bigint a, bigint b) { if(a.cmp(b)==0) return false; return true; } bigint bigint::operator|=(bigint b) { *this=*this|b; return *this; } bigint bigint::operator&=(bigint b) { *this=*this&b; return *this; } bigint bigint::operator^=(bigint b) { *this=*this^b; return *this; } bigint bigint::operator+=(bigint b) { *this=*this+b; return *this; } bigint bigint::operator-=(bigint b) { *this=*this-b; return *this; } bigint bigint::operator*=(bigint b) { *this=*this*b; return *this; } bigint bigint::operator/=(bigint b) { *this=*this/b; return *this; } bigint bigint::operator%=(bigint b) { *this=*this%b; return *this; } bigint bigint::operator<<=(bigint b) { *this=*this<>=(bigint b) { *this=*this>>b; return *this; } bigint bigint::operator++() { *this+=1; return *this; } bigint bigint::operator++(int dummy) { bigint old(*this); *this+=1; return old; } bigint bigint::operator--() { *this-=1; return *this; } bigint bigint::operator--(int dummy) { bigint old(*this); *this-=1; return old; } std::ostream& operator<<(std::ostream& os, bigint& b) { os<<((b.sign)?"-":"")<>(std::istream& is, bigint& b) { std::string numstr; is>>numstr; b=numstr.c_str(); return is; } bigint fac(bigint n) { bigint result=1; for(; n>0; n--) result*=n; return result; } int main() { clock_t start, end; std::ofstream fout; fout.open("result.txt"); bigint n=1; std::cout<<">"; std::cin>>n; while(n>0) { start=clock(); fout<"; std::cin>>n; } return 0; } 나눗셈에 오류 수정하고 bcd변환 속도 빠르게 해봤습니다. 공유하기 게시글 관리 Studying the Logical world! 'Team Projects > Suggested by Fanta' 카테고리의 다른 글 bigfloat 부등호 오류수정, 뺄셈 (4) 2009.03.02 발코딩 빅플롯 (0) 2009.02.24 'Team Projects/Suggested by Fanta' Related Articles bigfloat 부등호 오류수정, 뺄셈 발코딩 빅플롯