【經常使用算法總結——C++高精度運算】

  衆所周知,數與數進行運算時,當兩個數位數過大,咱們的電腦就會烤魚。因此咱們就出現了高精度運算,他的思想主要就是用字符串來存儲數據,再一位一位地分別計算(由於是字符,因此要記得-‘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 }

高精度開根

相關文章
相關標籤/搜索