function aaa(){ window.close(); } function ck() { console.profile(); console.profileEnd(); if(console.clear) { console.clear() }; if (typeof console.profiles =="object"){ return console.profiles.length > 0; } } function hehe(){ if( (window.console && (console.firebug || console.table && /firebug/i.test(console.table()) )) || (typeof opera == 'object' && typeof opera.postError == 'function' && console.profile.length > 0)){ aaa(); } if(typeof console.profiles =="object"&&console.profiles.length > 0){ aaa(); } } hehe(); window.onresize = function(){ if((window.outerHeight-window.innerHeight)>200) aaa(); }

【常用算法总结——C++高精度运算】

  众所周知,数与数进行运算时,当两个数位数过大,我们的电脑就会烤鱼。所以我们就出现了高精度运算,他的思想主要就是用字符串来存储数据,再一位一位地分别计算(因为是字符,所以要记得-‘0’或-48),达到最后的结果。所以,这篇文章将会告诉大家如何进行C++中的一些高精度运算。

如果有没写的,说明博客主智商阅历不够,以后就会有了(等着吧)

高精度加法

  一位一位的对着加,注意存储进位,小的数加完后把大数剩下的加进来,注意前导零和相加等于0

 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 }

以上代码是两个正数相加,若有负数,则需要另行判断:

  如果两个数都是负数,那么去掉负号,输出结果前加上负号即可。

  如果两个数有一个数是负数,先去掉负号,比较大小

    如果去掉负号的数大于另一个数,则需要用去掉负号的数减去另一个数,再输出负号(此时用高精度减法)

    如果去掉负号的数小于另一个数,则需要用另一个数减去去掉负号的数,(此时用高精度减法)

高精度减法

  一位一位的对着减,注意存储借位,小的数减完后把大数剩下的借位减进来,注意前导零和相减等于0

 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 }

以上代码是两个正数相减,若有负数,则需要另行判断:

  如果两个数都是负数,去掉负号,用后一个数减前一个数。

  如果两个数有一个数是负数,先去掉负号,比较大小

    如果第一个数是负数,相加,输出负号(此时用高精度加法)

    如果第二个数是负数,相加(此时用高精度加法)

高精度乘法

  相信大家都手动计算过乘法,就是一个数的每一位乘另一个数的每一位最后相加即可,当然,我们程序也是这样模拟

  这里有一个基本的知识点,相信大家在手写竖式的时候知道,就是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 }

高精度开根

posted @ 2019-07-12 16:30  华恋~韵  阅读(9926)  评论(6编辑  收藏  举报