主题:[原创]大数类 hugeint
rickone
[专家分:15390] 发布于 2005-05-15 16:41:00
#include<iostream.h>
class hugeint
{
public:
hugeint(int);
hugeint(long);
~hugeint();
hugeint& operator = (char*);
friend ostream& operator << (ostream&,hugeint&);
protected:
int *data;
long size;
};
#include<string.h>
#include<iomanip.h>
#include "hugeint.h"
hugeint::hugeint(int n)
{
size=(long)n/4;
data=new int[size];
for(long i=0;i<size;++i)data[i]=0;
}
hugeint::hugeint(long n)
{
size=n/4;
data=new int[size];
for(long i=0;i<size;++i)data[i]=0;
}
hugeint::~hugeint()
{
delete[]data;
}
hugeint& hugeint::operator = (char *str)
{
long len=strlen(str),count=0;
if(len>(size<<2))return *this;
char *p=str+len-1;
int t,i;
while(1)
{
if((p-str)<4)break;
t=0;
char *ph=p-3;
for(int i=0;i<4;++i)
{
t*=10;
t+=ph[i]-'0';
}
data[count++]=t;
p-=4;
}
t=0;
for(i=0;i<=p-str;++i)
{
t*=10;
t+=str[i]-'0';
}
data[count]=t;
return *this;
}
ostream& operator <<(ostream& out,hugeint& a)
{
int *p=a.data+a.size-1;
while(!*p)--p;
out<<*p--;
while(p>(a.data-1))
out<<setw(4)<<setfill('0')<<*p--;
return out;
}
#include "hugeint.h"
void main()
{
hugeint a(1000);
a="451234567864512164800012300000000";
cout<<a<<endl;
}
回复列表 (共18个回复)
沙发
rickone [专家分:15390] 发布于 2005-05-15 16:48:00
只完成了输入和输出部分,一起来做啊……
板凳
神父的咒语 [专家分:670] 发布于 2005-05-15 17:41:00
我写得了,用vector来写不多好吗?
3 楼
FancyMouse [专家分:13680] 发布于 2005-05-15 18:07:00
偶也在用C#写huge int。现在完成了加减法和大小比较。目前要解决的是乘除问题。
4 楼
rickone [专家分:15390] 发布于 2005-05-15 18:19:00
我乘已经完成了,现在在写除
5 楼
神父的咒语 [专家分:670] 发布于 2005-05-15 18:25:00
我用动态数组, 不用维护size.
6 楼
rickone [专家分:15390] 发布于 2005-05-15 18:55:00
什么动态数组?
7 楼
rickone [专家分:15390] 发布于 2005-05-15 18:58:00
已经完成了~~除法效率很慢,用的方法是循环减法,听人介绍的方法,没想到效率这么慢
以下是清单:
(今天只到这里)
8 楼
rickone [专家分:15390] 发布于 2005-05-15 19:02:00
#include<iostream.h>
class hugeint
{
public:
hugeint(int);
hugeint(long);
hugeint(hugeint&);
~hugeint();
inline long getsize(){return size;};
inline int elem(long index){return data[index];};
hugeint& operator = (char*);
hugeint& operator = (hugeint&);
protected:
void inverse();
void clear();
int inc();
int *data;
long size;
//friends:
friend ostream& operator << (ostream&,hugeint&);
friend hugeint operator + (hugeint&,hugeint&);
friend hugeint operator - (hugeint&,hugeint&);
friend hugeint operator * (hugeint&,hugeint&);
friend hugeint operator / (hugeint&,hugeint&);
friend hugeint operator % (hugeint&,hugeint&);
friend int add(hugeint&,hugeint&,int,int bitm=0);
friend int mul(hugeint&,int);
friend int div(hugeint&,hugeint&,hugeint&,hugeint&);
};
#include<string.h>
#include<iomanip.h>
#include "hugeint.h"
#define ERRORMSG "Over Flow!"
//public:
hugeint::hugeint(int n)
{
size=(long)n/4;
data=new int[size];
for(long i=0;i<size;++i)data[i]=0;
}
hugeint::hugeint(long n)
{
size=n/4;
data=new int[size];
for(long i=0;i<size;++i)data[i]=0;
}
hugeint::hugeint(hugeint& a)
{
size=a.getsize();
data=new int[size];
for(long i=0;i<size;++i)data[i]=a.elem(i);
}
hugeint::~hugeint()
{
delete[]data;
}
//protected:
void hugeint::inverse()
{
for(long i=0;i<size;++i)data[i]=9999-data[i];
}
void hugeint::clear()
{
for(long i=0;i<size;++i)data[i]=0;
}
int hugeint::inc()
{
int s=1;
for(long i=0;s&&i<size;++i)
{
int t=data[i]+s;
data[i]=t%10000;
s=t/10000;
}
if(s)return -1;
return 0;
}
//friends:
ostream& operator <<(ostream& out,hugeint& a)
{
int *p=a.data+a.size-1;
while(!*p)--p;
out<<*p--;
while(p>(a.data-1))
out<<setw(4)<<setfill('0')<<*p--;
return out;
}
hugeint& hugeint::operator = (char *str)
{
long len=strlen(str),count=0;
if(len>(size<<2))return *this;
char *p=str+len-1;
int t,i;
while(1)
{
if((p-str)<4)break;
t=0;
char *ph=p-3;
for(int i=0;i<4;++i)
{
t*=10;
t+=ph[i]-'0';
}
data[count++]=t;
p-=4;
}
t=0;
for(i=0;i<=p-str;++i)
{
t*=10;
t+=str[i]-'0';
}
data[count]=t;
return *this;
}
hugeint& hugeint::operator = (hugeint& a)
{
if(size!=a.getsize())return *this;
for(long i=0;i<size;++i)data[i]=a.elem(i);
return *this;
}
hugeint operator +(hugeint& a,hugeint& b)
{
hugeint temp=a;
if(add(temp,b,0))
cerr<<ERRORMSG<<endl;
return temp;
}
hugeint operator -(hugeint& a,hugeint& b)
{
hugeint temp1=a,temp2=b;
temp2.inverse();
add(temp1,temp2,1);
return temp1;
}
hugeint operator *(hugeint& a,hugeint& b)
{
hugeint temp1=a,temp2=temp1;
temp1.clear();
for(long i=0;i<b.size;++i)
{
temp2=a;
mul(temp2,b.data[i]);
add(temp1,temp2,0,i);
}
return temp1;
}
hugeint operator /(hugeint& a,hugeint& b)
{
hugeint stemp=a,rtemp=a;
if(div(a,b,stemp,rtemp))
cerr<<ERRORMSG<<endl;
return stemp;
}
hugeint operator %(hugeint& a,hugeint& b)
{
hugeint stemp=a,rtemp=a;
if(div(a,b,stemp,rtemp))
cerr<<ERRORMSG<<endl;
return rtemp;
}
int add(hugeint& a,hugeint& b,int s,int bitm)
{
long size;
if((size=a.size)!=b.size)return -2;
for(long i=bitm;i<size;++i)
{
int t=a.data[i]+b.data[i-bitm]+s;
a.data[i]=t%10000;
s=t/10000;
}
if(s)return -1;
return 0;
}
int mul(hugeint& a,int n)
{
int s=0;
for(long i=0;i<a.size;++i)
{
long t=a.data[i]*n+s;
a.data[i]=t%10000;
s=t/10000;
}
if(s)return -1;
return 0;
}
int div(hugeint& a,hugeint& b,hugeint& s,hugeint& r)//s=a/b,r=a%b
{
hugeint temp1=a,temp2=b,temp3=a;
s.clear();
while(1)
{
temp2=b;
temp2.inverse();
temp3=temp1;
if(!add(temp1,temp2,1))break;
if(s.inc())return -1;
}
r=temp3;
return 0;
}
#include "hugeint.h"
#define N 1000
void main()
{
hugeint a(N);
hugeint b=a,c=a;
a="300000000";
b="123432543";
cout<<a+b<<endl
<<a-b<<endl
<<a*b<<endl
<<a/b<<endl
<<a%b<<endl;
}
9 楼
zouyu1983 [专家分:1670] 发布于 2005-05-19 22:33:00
看你程序,是用万进制的,呵呵,万进制的除法可是慢到家了,我曾试过,放弃了,觉的采用百进制比较好,还有,既然用的是C++干嘛不用string呢,这样实现动态的比较容易,我以前也写了个,是十进制的,也贴出来了,在算法与数据结构板块,其中,除法是线性时间,不过代码量太大了,呵呵,当时为了提高时间效率,就对空间睁只眼,闭之眼了
10 楼
rickone [专家分:15390] 发布于 2005-05-20 15:55:00
我对这个也不太满意,以后有了时间再改进改进吧。
我来回复