高精度算法小结
其实 高精==高阶模拟
怎么讲?
- 高精加法:每一位对应相加,注意进位问题
- 高精减法:每一位对应相减,注意退位问题
- 高精乘法:每一位对应相加,注意进位问题
加法运算
每一位对应相加,满digit进1即可
#include <bits/stdc++.h>
using namespace std;
const int digit=10000;
const int maxx=4;
const int maxn=600;
char a[maxn],b[maxn];
struct Big
{
int a[maxn],n;
Big(){n=1;memset(a,0,sizeof(a));}
int& operator [] (int x){return a[x];}
Big(char *s)
{
memset(a,0,sizeof(a));
int len=strlen(s);
n=(len+maxx-1)/maxx;
int t=0,w=1;
for(int i=0;i<len;++i)
{
w=w*10;
if(i%maxx==0){w=1;++t;}
a[t]+=w*(s[i]-'0');
}
}
void Print()
{
printf("%d",a[n]);
for(int i=n-1;i>0;i--)
{
printf("%04d",a[i]);
}
}
}p,q,ans;
Big operator+(const Big &p,const Big &q)
{
Big c;
c.n=max(p.n,q.n);
for(int i=1;i<=c.n;i++)
{
c[i]+=p.a[i]+q.a[i];
c.a[i+1] += c.a[i] / digit;
c.a[i] %= digit;
}
if(c[c.n+1])++c.n;
return c;
}
void init()
{
freopen("Lg P1401.in","r",stdin);
}
void readdata()
{
scanf("%s\%s",a,b);
reverse(a,a+strlen(a));
reverse(b,b+strlen(b));
p=Big(a);
q=Big(b);
ans=p+q;
ans.Print();
}
int main()
{
// init();
readdata();
return 0;
}
减法运算
上述三种运算中,减法相对麻烦一些。注意判负
代码实现?
1.暴力模拟(见代码)
2.重载<运算符(见代码)
1.暴力模拟
#include <bits/stdc++.h>
using namespace std;
const int digit=10000;
const int maxx=4;
const int maxn=10005;
char a[maxn],b[maxn];
int f=1;
struct Big
{
int a[maxn],n;
Big(){n=1;memset(a,0,sizeof(a));}
int& operator [] (int x){return a[x];}
Big(char *s)
{
memset(a,0,sizeof(a));
int len=strlen(s);
n=(len+maxx-1)/maxx;
int t=0,w=1;
for(int i=0;i<len;i++)
{
w=w*10;
if(i%maxx==0){w=1;++t;}
a[t]=a[t]+w*(s[i]-'0');
}
}
void Print()
{
if(f==-1)printf("-");
printf("%d",a[n]);
for(int i=n-1;i>0;i--)
{
printf("%04d",a[i]);
}
}
}p,q,ans;
Big operator-(const Big &p,const Big &q)
{
Big c=p;
for(int i=1;i<=c.n;i++)
{
c[i]=c[i]-q.a[i];
if(c[i]<0)
{
c.a[i]=c.a[i]+digit;
--c[i+1];
}
}
while(c.n>0 && !c[c.n]) --c.n;
return c;
}
void init()
{
freopen("Lg P2142.in","r",stdin);
}
void readdata()
{
scanf("%s\n%s",a,b);
}
void work()
{
int lena=strlen(a),lenb=strlen(b);
if(lenb>lena)
{
swap(a,b);
f=-1;
}
if(f==1 && lenb==lena)
{
for(int i=lenb-1;i>=0;i--)
{
if(b[i]>a[i])
{
f=-1;
swap(a,b);
break;
}
}
}
reverse(a,a+strlen(a));
reverse(b,b+strlen(b));
p=Big(a);
q=Big(b);
ans=p-q;
ans.Print();
}
int main()
{
// init();
readdata();
work();
return 0;
}
乘法运算
Ai与Bi的乘积即为在【i+j-1】位上的值(满digit进位即可)
#include <bits/stdc++.h>
using namespace std;
const int maxn= 2005;
const int digit=10000;
const int maxx=4;
char a[maxn],b[maxn];
struct Big
{
int a[maxn],n;
Big(){n=1; memset(a,0,sizeof(a));}
int& operator[](int x){return a[x];}
Big(char *s)
{
memset(a,0,sizeof(a));
int len=strlen(s);
n=(len+maxx-1)/maxx;
int t=0,w=1;
for(int i=0;i<len;i++)
{
w=w*10;
if(i%maxx==0){++t;w=1;}
a[t]=a[t]+w*(s[i]-'0');
}
}
void Print()
{
printf("%d",a[n]);
for(int i=n-1;i>0;i--)
{
printf("%04d",a[i]);
}
}
}p,q,ans;
Big operator*(const Big &p,const Big &q)
{
Big c;
c.n=p.n+q.n-1;
for(int i=1;i<=p.n;i++)
{
for(int j=1;j<=q.n;j++)
{
c[i+j-1]+=p.a[i]*q.a[j];
c[i+j]+=(c[i+j-1])/digit;
c[i+j-1]=c[i+j-1]%digit;
}
}
if(c[c.n+1])++c.n;
return c;
}
void init()
{
freopen("Lg P1303.in","r",stdin);
}
void readdata()
{
scanf("%s\n%s",a,b);
reverse(a,a+strlen(a));
reverse(b,b+strlen(b));
p=Big(a);
q=Big(b);
ans=p*q;
ans.Print();
}
int main()
{
// init();
readdata();
return 0;
}