概述
當(dāng)計(jì)算的數(shù)值非常大或是對(duì)于計(jì)算的精度要求非常高時(shí),用已知的數(shù)據(jù)類型無法精確地表示數(shù)值○海可以采用數(shù)組來模擬大數(shù)運(yùn)算的過程卸夕。
高精度加法
兩個(gè)大數(shù)進(jìn)行相加計(jì)算時(shí)层释,要解決三個(gè)問題
- 如何存儲(chǔ)
- 如何計(jì)算
- 如何輸出答案
先解決第一個(gè)問題,數(shù)據(jù)地存儲(chǔ)快集,由于數(shù)據(jù)過于龐大贡羔,已知的數(shù)據(jù)類型無法精確地表示數(shù)值廉白,會(huì)發(fā)生數(shù)據(jù)溢出問題。此時(shí)可考慮將數(shù)據(jù)拆分乖寒,將大數(shù)分割成若干個(gè)0~9數(shù)字組成的整體猴蹂。這樣的結(jié)構(gòu)能讓我們聯(lián)想到數(shù)組。但是楣嘁,若是整數(shù)數(shù)組磅轻,在輸入時(shí)較難將數(shù)字存儲(chǔ)在各個(gè)元素空間內(nèi),此時(shí)可考慮使用字符串形式進(jìn)行輸入逐虚,在存儲(chǔ)后再進(jìn)行轉(zhuǎn)換聋溜。
const int maxn=1e10+5;
char s1[maxn]={0},s2[maxn]={0};
cin>>s1>>s2;
輸入完成后,再去考慮計(jì)算問題叭爱。首先撮躁,字符類型直接相加的結(jié)果并不正確,需要將其轉(zhuǎn)化為整數(shù)數(shù)字买雾“崖可利用ASCII碼差值來進(jìn)行處理。且在進(jìn)行計(jì)算時(shí)漓穿,模擬豎式加法計(jì)算過程嗤军,需要從低位開始向高位相加計(jì)算且注意過程中的進(jìn)位。在相加時(shí)晃危,加數(shù)和被加數(shù)位數(shù)可能不同叙赚,需要低位對(duì)齊。實(shí)現(xiàn)低位對(duì)齊可在轉(zhuǎn)換時(shí)進(jìn)行倒序存放山害。
// 轉(zhuǎn)換過程
int num[maxn]={0};
int len=strlen(s);
for(int i=0;i<len;i++)
{
num[i]=s[len-1-i]-'0';
}
倒序轉(zhuǎn)換好之后纠俭,在模擬豎式計(jì)算進(jìn)行處理。注意過程中的進(jìn)位浪慌。
int ans[maxn]={0};
for(int i=0;i<maxLen;i++)
{
ans[i]+=num1[i]+num2[i];
ans[i+1]=ans[i]/10;//進(jìn)位
ans[i]%=10;//保留余數(shù)
}
計(jì)算完成之后可以進(jìn)行輸出冤荆,這時(shí)候需要注意答案是倒著存放的,需要倒序進(jìn)行輸出并去除前導(dǎo)0;
int flag=0;
for(int i=maxLen+1;i>=0;i--)
{
if(ans[i]!=0||i==0) flag=1;
if(falg) cout<<ans[i];
}
高精度減法
高精度減法和高精度加法過程類似权纤,字符串輸入后模擬豎式進(jìn)行計(jì)算钓简。
前面數(shù)據(jù)輸入和倒置存放的過程相同就不再重復(fù)。再計(jì)算過程中需要注意的問題就是可能相減會(huì)出現(xiàn)負(fù)數(shù)汹想,兩數(shù)相減需要考慮絕對(duì)值大小問題外邓。
計(jì)算a-b,若a>=b,ans=a-b;若a<b,ans=-(b-a);故需要判斷大小,可根據(jù)長(zhǎng)度來判斷大小古掏,長(zhǎng)度相同則使用字符串比較函數(shù)损话,從字符串內(nèi)容上進(jìn)行判斷。
int len1=strlen(s1);
int len2=strlen(s2);
if((len1>len2) || (len2==len1&&strcmp(s1,s2)>=0 )
{
//ans=a-b;
for(int i=0;i<len1;i++)
{
if(num1[i]<num2[i]){
num1[i]+=10;
num1[i+1]--;
}
ans[i]=num1[i]-num2[i];
}
}else
{
//ans=-(b-a);
for(int i=0;i<len2;i++)
{
if(num2[i]<num1[i]){
num2[i]+=10;
num2[i+1]--;
}
ans[i]=num2[i]-num1[i];
}
cout<<"-";
}
算完后,再和前面一樣進(jìn)行倒序輸出答案丧枪,注意刪除前導(dǎo)0即可光涂。