高精度加法
数据极大,以数组形式存储数据
数据以低位向高位存储(方便进位,在数组后加数据要更加便捷)
int result[100010];
int index=0;
void add(int a[],int b[],int lena,int lenb){
int t=0;//记录是否需要进位
for(int i=0;i<lena||i<lenb;i++){
if(i<lena) t+=a[i];
if(i<lenb) t+=b[i];
result[index++]=t%10;
t/=10;
}
if(t) result[index++]=t%10;
}
高精度减法
与高精度加法类似
如果A-B中A<B则将减法变为-(B-A),这就保证了所传入的A的长度一定是大有B 的,所以只需要判断lena即可
int result[1000010];
判断A,B谁更大,选择不同模式
void sub(int numa[],int numb[],int lena,int lenb){
int t=0;//记录是否借位
for(int i=0;i<lena;i++){
t=numa[i]-t;
if(i<lenb) t-=numb[i];//判断B是否还有位
result[index++]=(t+10)%10;//2-3,t变成-1,借一位变成12-3=9落9,3-2=1,10%10抵消,为t本身
if(t<0) t=1;//借位在,这样在进行下一次运算时,上一位即可做到减一或不变
else t=0;
}
//去除前导0,123-120=003
}
//模板
#include <stdio.h>
#include <string.h>
#define N 100010
int result[N];
int count=0;
//判断是否A>=B
int check(int numa[],int numb[],int sza,int szb){
if(sza>szb) return 1;
else if(sza==szb){
for(int i=sza-1;i>=0;i--){
if(numa[i]<numb[i]) return 0;
else if(numa[i]==numb[i]){
continue;
}else{
return 1;
}
}
}else{
return 0;
}
}
void sub(int numa[],int numb[],int sza,int szb){
int t=0;
for(int i=0;i<sza;i++){
t=numa[i]-t;
if(i<szb) t-=numb[i];
result[count++]=(t+10)%10;
if(t<0) t=1;
else t=0;
}
//去除前导0
while(count>=1){//如果结果为0,保留最后一位0
if(result[--count]==0){//先减得到最高位,如果最高位是0,继续判断
;
}else{
break;//最高位不为0直接退出
}
}
}
int main()
{
char a[N],b[N];
scanf("%s",a);
scanf("%s",b);
int sza=strlen(a);
int szb=strlen(b);
int numa[N],numb[N];
int i,j;
for(i=sza-1,j=0;i>=0;i--,j++) numa[j]=a[i]-'0';
for(i=szb-1,j=0;i>=0;i--,j++) numb[j]=b[i]-'0';
if(check(numa,numb,sza,szb)){
sub(numa,numb,sza,szb);
for(i=count;i>=0;i--) printf("%d",result[i]);
}else{
printf("-");
sub(numb,numa,szb,sza);
for(i=count;i>=0;i--) printf("%d",result[i]);
//去除前导0过程中每次判断都会让count先减减,退出循环时count位必定不为0
}
return 0;
}
高精度乘法
思路:
以高精度数组每一位乘低精度数值(看成整体)区别于普通乘法运算
int result[100010];
int count=0;
void mul(int num,int b,int sz){
int t=0;//表示进位
for(int i=0;i<sz||t;i++){
if(i<sz) t+=num[i]*b;//以每一位乘低精度数值
result[count++]=t%10;//取得个位作为结果
t/=10;//表示进位
}
//去除前导0
}
/*
十进制表示
1476
1*10^3+4*10^2+7*10^1+6*10^0
*/
//模板
#include<stdio.h>
#include<string.h>
int result[100010];
int count=0;
void mul(int num[],int b,int sz){
int t=0;
for(int i=0;i<sz||t;i++){
if(i<sz) t+=num[i]*b;
result[count++]=t%10;
t/=10;
}
while(count>=1){
if(result[--count]==0);
else break;
}
}
int main()
{
char num[100010];
scanf("%s",num);
int b;
scanf("%d",&b);
int sz=strlen(num);
int number[100010];
for(int i=sz-1,j=0;i>=0;i--,j++) number[j]=num[i]-'0';
mul(number,b,sz);
for(int i=count;i>=0;i--) printf("%d",result[i]);
return 0;
}
高精度乘法(大数乘大数)
#include <stdio.h>
#include <string.h>
int res[100010];
int main()
{
char a[2010],b[2010];
scanf("%s",a);
scanf("%s",b);
int sza=strlen(a),szb=strlen(b);
int k=sza+szb;
int numa[10010],numb[10010];
for(int i=sza-1,j=0;i>=0;i--,j++) numa[j]=a[i]-'0';
for(int i=szb-1,j=0;i>=0;i--,j++) numb[j]=b[i]-'0';
for(int i=0;i<sza;i++){
for(int j=0;j<szb;j++){
res[i+j]+=numa[i]*numb[j];
}
}
int t=0;
for(int i=0;i<k;i++){
t+=res[i];
res[i]=t%10;
t/=10;
}
while(k>0&&res[k]==0) k--;
for(int i=k;i>=0;i--) printf("%d",res[i]);
return 0;
}
高精度除法
思路:
以高位开始,先取上一位的余数,最高位的上一位余数为0,余数*10加上下一位的数字,将所得结果与除数相除作为所得结果,下一位数位变成所得结果%除数。
int result[10010];
int count=0;
int begin=0;
int div(int num[],int sz,int b)
{
int r=0;//r 为余数
for(int i=sz-1;i>=0;i--)//以高位开始进行
{
r=r*10+num[i];
result[count++]=r/b;//高位结果按顺序存放
r%=b;
}
//去除前导0
while(begin<count-1){//保证有一个元素
if(num[++begin]==0);
else break;
}
return r;
}
//模板
#include <stdio.h>
#include <string.h>
int result[100010];
int count=0;
int begin=0;
int div(int num[],int sz,int b){
int r=0;
for(int i=sz-1;i>=0;i--){
r=r*10+num[i];
result[count++]=r/b;
r%=b;
}
while(begin<count-1){
if(result[++begin]==0);
else break;
}
return r;
}
int main()
{
char num[100010];
scanf("%s",num);
int b;
scanf("%d",&b);
int sz=strlen(num);
int number[100010];
for(int i=sz-1,j=0;i>=0;i--,j++) number[j]=num[i]-'0';
int r=div(number,sz,b);
for(int i=begin;i<count;i++) printf("%d",result[i]);
printf("\n%d",r);
return 0;
}