目錄
高精度加法
高精度乘法
高精度減法
? ? ? ? ?高精度除法
高精度模法
?文章來源地址http://www.zghlxwxcb.cn/news/detail-423933.html
高精度計算是模擬算法的一種,通過字符串和整型數組的使用,將加減乘除的豎式運算模擬出來,達到計算的目的。其步驟大致分為:一,將字符串數據存到整型數組中,二,模擬算法,不同的算式對準不同的模擬代碼,三,將保存的數據轉移。
高精度加法
void addhigh(char a[],char b[],char res[])//a,b分別為兩個加數的字符串,res返回答案
{
int a_num[2005],b_num[2005]; //保存字符串a,b的數組
for(int i=0;i<2005;i++) //初始化,保證開始每位上數字為0
a_num[i]=0,b_num[2005]=0;
//因為在豎式運算中我們是從低位算起,所以我們倒序將a,b存到數組里
for(int i=strlen(a)-1,j=0;i>=0;i--,j++) //倒序將a保存為數組,方便每一位的模擬
a_num[j]=a[i]-'0';
for(int i=strlen(b)-1,j=0;i>=0;i--,j++) //倒序將b保存為數組,方便每一位的模擬
b_num[j]=b[i]-'0';
int lenth_max = strlen(a)>strlen(b)?strlen(a):strlen(b); //計算長度,方便記錄位數
for(int i=0;i<lenth_max;i++) //加法運算的核心,其他(乘法減法)都是這里來實現
{
a_num[i]+=b_num[i]; //a的每一位加上b的每一位;
if(a_num[i]>=10) //因為是十進制,
a_num[i+1]+=a_num[i]/10; //下一位加上該為的10的除數,模擬進位
a_num[i]=a_num[i]%10; //大于十我們需要取10的模數,
}//提示,如果是其他進制,只需要將10變?yōu)槠渌麛? if(a_num[lenth_max]!=0) //因為加法最多只能進一位
lenth_max++;
for(int i=lenth_max-1,j=0;i>=0;i--,j++)//將結果轉移到字符串中
res[j]=a_num[i]+'0';
res[lenth_max]='\0';//將結果后打上終止符方便輸出
}
觀察代碼發(fā)現實際上實現高精度加法的核心在于中間的一個for循環(huán),其他全都是形同的預處理,所以我們可以想到高精度乘法的處理方式
高精度乘法
void multihigh(char a[],char b[],char res[])
{
int lenth_a=strlen(a), lenth_b=strlen(b);
int a_num[2005],b_num[2005],res_num[2005];
for(int i=0;i<2005;i++)
a_num[i]=b_num[i]=res_num[i]=0;
for(int i=1;i<=lenth_a;i++) a_num[i]=a[lenth_a-i]-'0';
for(int i=1;i<=lenth_b;i++) b_num[i]=b[lenth_b-i]-'0';
//-----------------------------------------------核心代碼
for(int i=1;i<=lenth_a;i++)//通過兩重的循環(huán)實現每次數乘玩之后都要乘10
for(int j=1;j<=lenth_b;j++)
res_num[i+j-1]+=a_num[i]*b_num[j];//a,b的每一位相乘
for(int i=1;i<lenth_a+lenth_b;i++)//十進制處理,大于10模除進位
if(res_num[i]>=10){
res_num[i+1]+=res_num[i]/10;
res_num[i]%=10;
}
int lenth_max=lenth_a+lenth_b;//兩數相乘后,結果的位數不會比兩加數的位數之和大,方便后面找位數時降低循環(huán)次數
while(res_num[lenth_max]==0&&lenth_max>1) lenth_max--;//從后找第一個非0的元素即為最高位數,從前找0不行;
//-------------------------------------------------核心代碼
for(int i=lenth_max,j=0;i>0;i--,j++) res[j]=res_num[i]+'0';
res[lenth_max]='\0';
}
乘法和加法基本一樣,但是高精度減法卻又多了正負的判斷。
高精度減法
首先寫a字符串>b字符串的減法函數,這樣如果a<b時只需將a,b位置顛倒;
void minHighlong(char a[],char b[],char res[])
{
int a_num[2005],b_num[2005];
int lenth_max=strlen(a);
for(int i=0;i<2005;i++)
a_num[i]=0,b_num[2005]=0;
for(int i=strlen(a)-1,j=0;i>=0;i--,j++)
a_num[j]=a[i]-'0';
for(int i=strlen(b)-1,j=0;i>=0;i--,j++)
b_num[j]=b[i]-'0';
//-----------------------------------------核心代碼
for(int i=0;i<strlen(a);i++)
{
a_num[i]-=b_num[i]; //a的數組減去b的數組
if(a_num[i]<0) a_num[i]+=10,a_num[i+1]--;
//如果a的該位數小于0,將取前一位數的10來填補,同時前一位減去1
}
//-----------------------------------------核心代碼
while(a_num[lenth_max]==0&&lenth_max>0) lenth_max--;
for(int i=lenth_max,j=0;i>=0;i--,j++)
res[j]=a_num[i]+'0';
res[lenth_max+1]='\0';
}
接下來我們只需要寫個函數實現判斷a和b的大小關系,代碼如下
int compare(char a[],char b[])
{
if(strlen(a)<strlen(b))//比較長度,a<b的話返回0;
return 0;
if(strlen(a)>strlen (b))//同理
return 1;
else{
for(int i=strlen(a);i>=0;i--)//長度相同逐位數去比較,由高向低比較數字大小
if(a[i]<b[i])
return 0;
}
return 1;
}
不能用strcmp(),strcmp() 會根據 ASCII 編碼依次比較 str1 和 str2 的每一個字符,直到出現不到的字符,或者到達字符串末尾(遇見\0
)。不符合數學比大小。
最后將這兩個函數組合起來就形成了最終函數
void minHigh(char a[],char b[],char res[])
{
if(compare(a,b))//比較后確定ab的位置
minHighlong(a,b,res);
else{
minHighlong(b,a,res);//將結果加工成負數
res[strlen(res)+1]='\0';//加休止符確定末尾
for(int i=strlen(res);i>0;i--) res[i]=res[i-1];//從末尾向后移動一位
res[0]='-';//加上符號
}
}
高精度除法
高精除低精度我們可以模擬,但是高精除高精我們只能利用高精度減法一個一個減去,最后計算出結果,同時我們的結果也可能是高精度,所以在結果的處理上我們需要用高精度加法。
void dividHigh(char a[],char b[],char res[])
{
res[0]='0';
res[1]='\0';
char one[2];
one[0]='1';
one[1]='\0';
while(compare(a,b))//當a<b時說明不能除了,結束
{
addhigh(res,one,res);//結果增加
minHigh(a,b,a);//減去一個除數
}
}
高精度除法用的都是之前的加減函數來實現,這樣效率特別低,所以判斷條件時能用高精除低精時,盡量用高精除低精,其中高精除低精核心代碼如下:
for(i=strlen(a)-1;i>=0;i--){
reminder=reminder*10+a_num[i]; //模擬除法
ans[i]=reminder/b;
reminder%=b;
}
高精度模法
高精度模低精度的話,我們只需讀一位(得乘10)模一位就可以得到最終答案,
int mod(string a, int b) {
int d = 0;
for (int i = 0; i < a.size(); i++)
{
d = (d * 10 + (a[i] - '0')) % b;
}
return d;
}
每次模之后可以將數字不斷的縮小到精度以內,但是高精度模高精度卻不可以,所以我們在處理高精模高精度時,只需將除法改下就可以了,即利用高精循環(huán)去減,判斷大小即可,這里就不贅述了
?
高精度運算就在于對每一位運算的模擬,處理好進位,拿一,相乘之后,就可實現整個運算。文章來源:http://www.zghlxwxcb.cn/news/detail-423933.html
?
到了這里,關于C語言 加減乘除模 的 高精度計算 (超詳細)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!