高精度加减乘除模板
本代码模板提供了高精度加法,减法。高精乘高精,高精乘低精,高精除低精,高精除高精。且都已函数封装的形式给出。(思路就是列竖式。加减乘都从最低位开始。除从最高位开始)
#include<cstdio> #include<algorithm> #include<vector> #include<cstring> #define MAXN 6666 using namespace std; typedef long long ll; char s1[MAXN],s2[MAXN]; int a[MAXN],b[MAXN],c[MAXN],flag; template<int len> void Dh(char s[],int (&a)[len]){//将字符串数组逆序存储到整形数组当中 memset(a, 0, sizeof(a)); a[0]=strlen(s); for(int i=1;i<=a[0];i++) a[i]=s[a[0]-i]-'0'; } int Bijiao(int a[],int b[]){//比较,a大于b时返回1,小于b时返回0,等于b时返回2 if(a[0]!=b[0]) return a[0]>b[0]?1:0; for(int i=a[0];i>0;i--){ if(a[i]!=b[i]) return a[i]>b[i]?1:0; if(i==1) return 2; } } void Add(int a[],int b[],int c[]){//高精加 两个正整数 令a+b=c; int n=max(a[0],b[0]); int temp=0; for(int i=1;i<=n;i++){ c[i] = (a[i]+b[i]+temp)%10; temp=(a[i]+b[i]+temp)/10; } if(temp) c[n+1]=temp; if(temp>0) c[0] = n+1; else c[0] =n; } void Jian(int a[],int b[],int c[]){//高精减,2个正整数,令a-b=c flag=Bijiao(a,b);//a大返回1,b大返回0 if(flag==2){ c[0]=1; c[1]=0; return; } int n=max(a[0],b[0]); int temp =0; if(flag) for(int i=1;i<=n;i++){ c[i]=(a[i]-b[i]-temp+10)%10; if(a[i]<b[i]+temp) temp =1; else temp =0; } else//当a<b时,记得输出负号。 for(int i=1;i<=n;i++){ c[i]=(b[i]-a[i]-temp+10)%10; if(b[i]<a[i]+temp) temp =1; else temp =0; } while(c[n]==0) n--; c[0]=n; } template<int len> void Multi(int a[],int b[],int (&c)[len]){//高精乘,a*b=c memset(c,0,sizeof(c)); for(int i=1;i<=a[0];i++) for(int j=1;j<=b[0];j++){ c[i+j-1]=c[i+j-1]+a[i]*b[j]; c[i+j]=c[i+j]+c[i+j-1]/10; c[i+j-1]=c[i+j-1]%10; } int n=a[0]+b[0]; while(c[n]==0&&n>0) n--; if(c[1]==0&&n==0) c[0]=1; else c[0]=n; } void Multid(int a[],long long key) {//高精*低精a=a*key,key是低精度数 int i,k; if (key==0){ memset(a,0,sizeof(a)); a[0]=1; return; } //单独处理key=0 for(i=1;i<=a[0];i++) a[i] = a[i]*key;//先每位乘起来 for(i=1;i<=a[0];i++){ a[i+1]+=a[i]/10; a[i]%=10; } //进位 //注意上一语句退出时i=a[0]+1 while(a[i]>0){ a[i+1] = a[i]/10; a[i] = a[i]%10; i++; a[0]++; } //继续处理超过原a[0]位数的进位,修正a的位数 return; } void Chujian(int a[],int b[]){ //用于高精除当中的减法。a-b.且将结果存入a中 int pd,i; pd=Bijiao(a,b); //调用函数比较ab大小 if (pd==2) { a[0]=0; return; } //相等 if (pd==1){//a>b时才做处理 for (i=1;i<=a[0];i++){ if (a[i]<b[i]) { a[i+1]--;a[i]+=10; } //若不够减上借一位 if (a[i]>=b[i]) a[i]-=b[i]; } while((a[a[0]]==0)&&(a[0]>0)) a[0]--; return; } } void numcpy(int p[],int q[],int det){ //高精除前置函数。将数组右移,使两个数组右端对齐,形参q数组储存右移后的结果.即56变成00056(原值为65变成65000) for (int i=1;i<=p[0];i++) q[i+det-1]=p[i];// q[0]=p[0]+det-1; } void Chu(int a[],int b[],int c[]){//高精除法,a/b=c。把除法试商转化为连减。 int i,tmp[MAXN]; c[0]=a[0]-b[0]+1; for (i=c[0];i>0;i--){ memset(tmp,0,sizeof(tmp)); //tmp数组清零 numcpy(b,tmp,i); //将除数b右移后复制给tmp数组,注意用i控制除数位数 while (Bijiao(a,tmp)){//如果a>tmp说明a/temp>0,答案++ c[i]++; Chujian(a,tmp);//令a-=temp。再倒回 } //减法模拟除法,并计数 } while((c[c[0]]==0)&&(c[0]>0)) c[0]--; // 控制最高位的0 } void Chud(int a[],long long key,int c[]){//高精/低精 。a/key=c.key为低精数。 int temp=0; for(int i=a[0];i>=1;i--){ temp = temp*10+a[i]; c[i] = temp/key; temp = temp%key; } c[0]=a[0]; while(c[c[0]]==0&&c[0]>1) c[0]--; } int main(){ int t,id=0; scanf("%s%s",&s1,&s2); Dh(s1,a); Dh(s2,b); // Add(a,b,c);//高精加 // Jian(a,b,c); //高精减 // if(!flag)//高精减的正负 // printf("-"); // Multi(a,b,c);//高精乘 // Chud(a,2,c);//高精除低精 // Chu(a,b,c); //高精除 for(int i=c[0];i>=1;i--)//输出高精加减乘 printf("%d",c[i]); // Multid(a,7);//高精乘单精 // for(int i=a[0];i>=1;i--)//输出高精* 单精 // printf("%d",a[i]); printf("\n"); }

浙公网安备 33010602011771号