高精度四则运算

 高精度运算,是指参与运算的数(加数,减数,因子……)范围大大超出了标准数据类型(整型,实型)能表示的范围的运算。例如,求两个200位的数的和。这时,就要用到高精度算法了。

加减乘利用模拟竖式运算的方法很简单就可以实现。
除法有点麻烦。
关于除法,网上所说的做法一般有下面几种。
1.枚举结果,利用乘法验证。
2.不断使用减法。
3.二分答案 他们都高大上地丢下一句二分答案,所以我就推测大概是第一种的优化版,二分枚举答案,范围为1..本身,然后利用乘法验证。

1,2中显然时间复杂度十分高,为o(n*k1*k2)
n为被除数的数字大小,k1*k2为两个数的位数。
显然是十分不理想的算法。

3.的话,就是logn*k1*k2
虽然依然不好,但是优化了很不少了。
然而用3的话还要先解决高精度数除以int的算法。

下面给出高精度四则运算的代码。
假如有对于除法更好的算法,请务必赐教。

 
#include <iostream>

#include <sstream>
#include <string>
 
#define rep(i,a,b) for (int i=a;i<=b;i++)
 
using namespace std;
 
const int N=1000;
 
struct high_precision{
int dat[N+1];
int size;
high_precision &operator=(high_precision a);
high_precision (){
size=0;
memset(dat,0,sizeof(dat));
}
};
 
istream &operator >>(istream&,high_precision&);
ostream &operator <<(ostream&,high_precision);
high_precision operator +(high_precision,high_precision);
high_precision operator -(high_precision,high_precision);
high_precision operator *(high_precision,high_precision);
high_precision operator /(high_precision,int);
bool operator >(high_precision,high_precision);
bool operator <(high_precision,high_precision);
bool operator ==(high_precision,high_precision);
 
high_precision a,b;
 
int main(){
cin>>a>>b;
 
cout<<"a+b="<<a+b<<endl;
cout<<"a-b="<<a-b<<endl;
cout<<"a*b="<<a*b<<endl;
}
 
istream &operator >>(istream &cin,high_precision &a){
string str;
stringstream ss;
int n;
 
cin>>str;
a.size=0;
while(str.length()>4){
n=str.length();
ss<<str.substr(n-4,4);
ss>>a.dat[++a.size];
ss.clear();
str=str.substr(0,n-4);
}
 
ss<<str;
ss>>a.dat[++a.size];
 
return cin;
}
 
ostream &operator <<(ostream &cout,high_precision a){
cout<<a.dat[a.size];
for (int i=a.size-1;i>=1;i--){
if (a.dat[i]<1000)
if (a.dat[i]<100)
if (a.dat[i]<10)
cout<<"000";
else cout<<"00";
else cout<<"0";
cout<<a.dat[i];
}
return cout;
}
 
high_precision operator +(high_precision a,high_precision b){
a.size=max(a.size,b.size);
rep(i,1,a.size){
a.dat[i]+=b.dat[i];
a.dat[i+1]+=a.dat[i]/10000;
a.dat[i]%=10000;
}
if (a.dat[a.size+1])
a.size++;
return a;
}
 
high_precision operator -(high_precision a,high_precision b){
//as there is no flag to show the number is positive or not
//so we'got to assume that a is always bigger than b or it just will go wrong
rep(i,1,a.size){
a.dat[i]-=b.dat[i];
if (a.dat[i]<0){
a.dat[i]+=10000;
a.dat[i+1]--;
}
}
while(a.dat[a.size]==0)
a.size--;
return a;
}
high_precision operator *(high_precision a,high_precision b){
high_precision c;
c.size=a.size+b.size;
 
rep(i,1,a.size)
rep(j,1,b.size)
c.dat[i+j-1]+=a.dat[i]*b.dat[j];
rep(i,1,c.size)
if (c.dat[i]>10000){
c.dat[i+1]+=c.dat[i]/10000;
c.dat[i]%=10000;
}
while(c.dat[c.size]==0)
c.size--;
return c;
}
 
high_precision operator /(high_precision a,int b){
int c(0);
for (int i=a.size;i>=1;i--){
c=c*10000+a.dat[i];
a.dat[i]=c/b;
c%=b;
}
while(a.dat[a.size]==0)
a.size--;
return a;
}
 
bool operator >(high_precision a,high_precision b){
if (a.size>b.size)
return 1;
else if (a.size<b.size)
return 0;
for (int i=a.size;i>=1;i--)
if (a.dat[i]>b.dat[i])
return 1;
else if (a.dat[i]<b.dat[i])
return 0;
return 0;
}
 
bool operator ==(high_precision a,high_precision b){
if (a.size!=b.size)
return 0;
rep(i,1,a.size)
if (a.dat[i]!=b.dat[i])
return 0;
return 1;
}
 
bool operator <(high_precision a,high_precision b){
if ((a>b) || (a==b))
return 0;
return 1;
}
 
high_precision &high_precision::operator=(high_precision a){
this->size = a.size;
    rep(i,1,this->size)
    this->dat[i]=a.dat[i];
    return *this;
    /*
     remove all "this->" and don't return anything
     it works too
    */
}

 

posted on 2014-01-02 13:33  杰斯特丹第  阅读(348)  评论(0编辑  收藏  举报

导航