【常用算法總結——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 }

高精度開根


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM