高精度算法
高精度的主要思路是:
- 用数组保存数位
- 模拟人的计算方式,计算各个数位
高精度加法
求 A + B
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1e6+6;
int a[N],b[N],c[N];
char s[N];
int L;
int la,lb;
void add(int *a,int *b){
int t;
for(int i=0;i<la||i<lb;i++){
t = a[i] + b[i] + c[i];
c[i] = t%10;
c[i+1] = t/10;
L = i;
}
if(c[L+1])L++;
}
int main(){
scanf("%s",s);
la = int(strlen(s));
for(int i=0,j=la-1;i<la;i++)
a[j--] = s[i] - '0';
scanf("%s",s);
lb = int(strlen(s));
for(int i=0,j=lb-1;i<lb;i++)
b[j--] = s[i] - '0';
add(a,b);
for(int i=L;i>=0;i--)
printf("%d",c[i]);
}
高精度减法
求 A - B
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1e6+6;
int a[N],b[N],c[N];
char sa[N],sb[N];
int la,lb,lc;
bool big(int *a,int *b){
// a>=b;
if(la!=lb)return la>=lb;
for(int i=la-1;i>=0;i--){
if(a[i]==b[i])
continue;
return a[i] > b[i];
}
return true;
}
void sub(int *a,int *b){
if(!big(a,b)) swap(a,b);
int cnt=0,t;
int L = max(la,lb);
for(int i=0;i<L;i++){
t = a[i] - b[i] - cnt;
c[i] = (t+10)%10;
cnt = t<0? 1:0;
lc = i;
}
for(;c[lc]==0&&lc>0;lc--);
}
int main(){
scanf("%s",sa);
la = strlen(sa);
for(int i=0,j=la-1;i<la;i++)
a[j--] = sa[i] - '0';
scanf("%s",sb);
lb = strlen(sb);
for(int i=0,j=lb-1;i<lb;i++)
b[j--] = sb[i] - '0';
sub(a,b);
if(!big(a,b))printf("-");
for(int i=lc;i>=0;i--)
printf("%d",c[i]);
}
说来惭愧,sub那里最开始我写的是
void sub(int* a,int *b){
if(!big(a,b)) return sub(a,b);
...
因为这个一直在memory limit exceed 的报错误,真的憨憨,最后是在Xcode里检查出来错,发现一直死循环。
高精度乘法
计算A x b
A是大数,且假定b不超过10000
#include <iostream>
#include <cstring>
using namespace std;
#define ll long long
const int N = 1e6+6;
int a[N],b,c[N],la,lc;
char s[N];
void mulitply(){
int cnt=0,t;
lc = 0;
for(int i = 0;i<la+6;i++){
// 因为b最大是10000,所以a的一个位乘b最大是90000,最多进5位,我们取到6位,如果有多的0,在后面处理就行。
t = a[i] * b + cnt;
c[i] = t % 10;
cnt = t / 10;
lc++;
}
// 处理多余的前导0,至少保留一个0
while(c[lc] == 0 && lc > 0)lc--;
return;
}
int main(){
scanf("%s",s);
scanf("%d",&b);
la = (int)strlen(s);
for(int i = 0,j = la-1;i<la;i++)a[i] = s[j--]-'0';
mulitply();
for(int i=lc;i>=0;i--)
printf("%d",c[i]);
printf("\n");
return 0;
}
高精度除法
A / b
求商和余数
这个我感觉写的好烂,代码功底太差了
#include <iostream>
#include <cstring>
using namespace std;
#define ll long long
const int N = 1e6+6;
int a[N],b,c[N],la,lc,r,extra;
char s[N];
void division(){
int cnt=0,t;
for (int i=la-1; i>=0; i--) {
t = cnt * 10 + a[i];
c[lc++] = t / b;
cnt = t % b;
}
//前导 0 的处理
while(c[extra] == 0 && extra<lc)extra++;
r = cnt;
return;
}
int main(){
scanf("%s%d",s,&b);
la = (int)strlen(s);
for(int i = 0,j = la-1;i<la;i++)a[i] = s[j--]-'0';
division();
if(extra==lc)printf("0\n");
else{
for(int i=extra;i<lc;i++)
printf("%d",c[i]);
printf("\n");
}
printf("%d\n",r);
return 0;
}