众所周知,数与数进行运算时,当两个数位数过大,咱们的电脑就会烤鱼。因此咱们就出现了高精度运算,他的思想主要就是用字符串来存储数据,再一位一位地分别计算(由于是字符,因此要记得-‘0’或-48),达到最后的结果。因此,这篇文章将会告诉你们如何进行C++中的一些高精度运算。c++
若是有没写的,说明博客主智商阅历不够,之后就会有了(等着吧)数组
一位一位的对着加,注意存储进位,小的数加完后把大数剩下的加进来,注意前导零和相加等于0spa
1 #include<bits/stdc++.h> 2 using namespace std; 3 int c[10000001];//记录结果的数组 4 string a,b; 5 long long k=0,r=0,i,j; 6 bool flag; 7 int main() 8 { 9 cin>>a>>b;//输入须要作操做的字符串 10 if(a.size()<b.size()||a.size()==b.size()&&a<b)//把大的字符串放前面,方便操做 11 { 12 swap(a,b); 13 } 14 for(i=a.size()-1,j=b.size()-1;j>=0;i--,j--)//从最低位相加,相加他们的公共部分,因此j>=0 15 { 16 c[k++]=(r+a[i]-'0'+b[j]-'0')%10;//两个位数和进位的相加后取个位 17 r=(r+a[i]-'0'+b[j]-'0')/10;//记录进位 18 } 19 while(i>=0)//再把剩下的继续加 20 { 21 c[k++]=(r+a[i]-'0')%10;//位数和进位的相加后取个位 22 r=(r+a[i]-'0')/10;//记录进位 23 i--; 24 } 25 if(r)c[k++]=r;//若是还有进位,进到最高位 26 for(i=k-1;i>=0;i--)//输出 27 { 28 if(c[i]!=0||flag)//防止前导0输出的操做 29 { 30 cout<<c[i]; 31 flag=true; 32 } 33 } 34 if(flag==false)cout<<0;//若是都没有输出,说明相加结果为0,应当输出0 35 return 0; 36 }
以上代码是两个正数相加,如有负数,则须要另行判断:code
若是两个数都是负数,那么去掉负号,输出结果前加上负号便可。blog
若是两个数有一个数是负数,先去掉负号,比较大小ci
若是去掉负号的数大于另外一个数,则须要用去掉负号的数减去另外一个数,再输出负号(此时用高精度减法)字符串
若是去掉负号的数小于另外一个数,则须要用另外一个数减去去掉负号的数,(此时用高精度减法)博客
一位一位的对着减,注意存储借位,小的数减完后把大数剩下的借位减进来,注意前导零和相减等于0string
1 #include<bits/stdc++.h> 2 using namespace std; 3 int c[10000001];//记录结果的数组 4 string a,b; 5 long long k=0,r=0,i,j; 6 bool flag; 7 int main() 8 { 9 cin>>a>>b;//输入须要作操做的字符串 10 if(a.size()<b.size()||a.size()==b.size()&&a<b)//把大的字符串放前面,方便操做 ,还要判断相减是否为负数 11 { 12 cout<<"-"; 13 swap(a,b); 14 } 15 for(i=a.size()-1,j=b.size()-1;j>=0;i--,j--) 16 { 17 c[k++]=(a[i]-b[j]-r);//两个位数相减再减去接的位数 18 r=0;//清零标记 19 if(c[k-1]<0){c[k-1]+=10;r=1;}//若是是负数就借十,并标记 20 } 21 while(i>=0)剩下的继续减 22 { 23 c[k++]=(a[i]-'0'-r);//减去借的 24 r=0;//清零标记 25 if(c[k-1]<0){c[k-1]+=10;r=1;}//若是是负数就借十,并标记 26 i--; 27 } 28 for(i=k-1;i>=0;i--)//输出 29 { 30 if(c[i]!=0||flag)//防止前导0输出的操做 31 { 32 cout<<c[i]; 33 flag=true; 34 } 35 } 36 if(flag==false)cout<<0;//若是都没有输出,说明相减结果为0,应当输出0 37 return 0; 38 }
以上代码是两个正数相减,如有负数,则须要另行判断:it
若是两个数都是负数,去掉负号,用后一个数减前一个数。
若是两个数有一个数是负数,先去掉负号,比较大小
若是第一个数是负数,相加,输出负号(此时用高精度加法)
若是第二个数是负数,相加(此时用高精度加法)
相信你们都手动计算过乘法,就是一个数的每一位乘另外一个数的每一位最后相加便可,固然,咱们程序也是这样模拟
这里有一个基本的知识点,相信你们在手写竖式的时候知道,就是c[i+j]+=a[i]+b[j](由于a和b都是从0下标开始的,若是从下标1开始,就c[i+j-1]+=a[i]+b[j])
1 #include<bits/stdc++.h> 2 using namespace std; 3 string a,b; 4 int k; 5 int c[1000001]; 6 int main() 7 { 8 cin>>a>>b; 9 reverse(a.begin(),a.end()); 10 reverse(b.begin(),b.end()); 11 for(int i=0;i<a.size();i++) 12 { 13 for(int j=0;j<b.size();j++) 14 { 15 c[i+j]+=(a[i]-48)*(b[j]-48); 16 } 17 } 18 for(k=0;k<=a.size()+b.size();k++) 19 c[k]+=c[k-1]/10,c[k-1]%=10; 20 while(!c[k]&&k>=1)k--; 21 for(;k>=0;k--) 22 cout<<c[k]; 23 return 0; 24 }
手动模拟除法过程,每次读到新位计算出被除数,而后计算。大致就是一位一位的作减法操做。
1 #include<bits/stdc++.h> 2 using namespace std; 3 int c[10000001];//记录结果的数组 4 string s; 5 long long k=0,a,b,i; 6 bool flag; 7 int main() 8 { 9 cin>>s>>b;//输入被除数和除数 10 for(int i=0;i<s.size();i++)//从高位开始,一位一位向低位 11 { 12 a=a*10+s[i]-'0';//加上被除数的这一位 13 c[k++]=a/b; 14 a%=b;//除完了 15 } 16 for(i=0;i<k;i++)//由于是从高位到低位,因此要反着输出 17 { 18 if(c[i]!=0||flag)//防止前导0输出的操做 19 { 20 cout<<c[i]; 21 flag=true; 22 } 23 } 24 if(flag==false)cout<<1;//若是都没有输出,说明相减结果为1,应当输出1 25 return 0; 26 }
以上代码是两个正数相除,如有负数,则须要另行判断:
若是两个数都是负数,去掉负号,无论他。
若是两个数有一个数是负数,去掉负号,输出时加上。
这个和高精度除法差很少,不须要记录和输出商就差很少
1 #include<bits/stdc++.h> 2 using namespace std; 3 string s; 4 long long k=0,a,b,i; 5 bool flag; 6 int main() 7 { 8 cin>>s>>b;//输入被除数和除数 9 for(int i=0;i<s.size();i++)//从高位开始,一位一位向低位 10 { 11 a=a*10+s[i]-'0';//加上被除数的这一位 12 a%=b;//一直取余 13 } 14 cout<<a; 15 return 0; 16 }