大整数运算
文章目錄
- 大整數(shù)的存儲(chǔ)
- 比較大小
- 高精度加法
- 高精度減法
- 高精度乘法
- 高精度除法
- 完整代碼演示(加法)
大整數(shù)的存儲(chǔ)
- 定義結(jié)構(gòu)體
- 將整數(shù)轉(zhuǎn)換為bign
比較大小
/*比較a和b大小,a大 相等 小分別返回1 0 -1*/ int compare(bign a, bign b){if(a.len > b.len){ //a大 return 1;}else if(a.len<b.len){ //a小 return -1;}//a b 長(zhǎng)度相等 else{for(int i=a.len-1; i>=0; i--){ //從高位往地位比較 if(a.d[i]>b.d[i]){ //只要有一位a大則a大 return 1;}else if(a.d[i]<b.d[i]){ //只要有一位a小則a小 return -1;}}return 2; //兩數(shù)相等 } }高精度加法
bign add(bign a, bign b){bign c;int carry = 0; //進(jìn)位 for(int i=0; i<a.len||i<b.len; i++){ //以較長(zhǎng)的為界限 int temp = a.d[i] +b.d[i] + carry; //兩個(gè)對(duì)應(yīng)和進(jìn)位相加c.d[c.len++ ] = temp % 10; //個(gè)位數(shù)為該為結(jié)果carry = temp /10; //十位數(shù)為新的進(jìn)位 }if(carry!=0){ //如果最后進(jìn)位不為0,則直接賦給結(jié)果的最高位 c.d[c.len++] = carry;} return c; }高精度減法
bign sub(bign a, bign b){bign c;for(int i=0; i<a.len||b.len; i++){if(a.d[i]<b.d[i]){ //不夠減 a.d[i+1]--; //向高位借位 a.d[i] += 10; //當(dāng)前位加10 }c.d[c.len++] = a.d[i] - b.d[i]; //減法結(jié)果為當(dāng)前位結(jié)果 }while(c.len-1>=1 && c.d[c.len-1]==0){ //去除高位的0同時(shí)至少保留一位最低位 c.len--;} return c; }高精度乘法
/*高精度a*b*/ bign multi(bign a, int b){bign c;int carry = 0;for(int i=0; i<a.len; i++){int temp = a.d[i] * b + carry;c.d[c.len++] = temp % 10;carry = temp / 10;}//和加法不一樣 乘法的進(jìn)位可能不止一位,因此用while while(carry!=0){c.d[c.len++] = carry % 10;carry /= 10;}return c; }高精度除法
/*高精度a/b, r為余數(shù)*/ bign divide(bign a, int b, int &r){bign c;//被除數(shù)的每一位和商的每一位是一一對(duì)應(yīng)的,因此先令長(zhǎng)度相等 c.len = a.len;for(int i=a.len-1; i>=0; i--){ //從高位開始 r = r * 10 + a.d[i]; //和上一位遺留的余數(shù)相加 if(r<b){ //不夠除 該位為0 c.d[i] = 0;}else{ //夠除 c.d[i] = r / b; //商 r = r%b; //獲得新的余數(shù) }}//去除高位的0,同時(shí)至少保留一位最低位 while(c.len-1>=1 && c.d[c.len-1]==0){c.len--;}return c; }完整代碼演示(加法)
#include <cstdio> #include <cstring>struct bign{int d[1000];int len;bign(){memset(d, 0, sizeof(d));len = 0;} }; /*將整數(shù)轉(zhuǎn)換為bign*/ bign change(char str[]){bign a;a.len = strlen(str);for(int i=0; i<a.len; i++){a.d[i] = str[a.len-i-1] - '0';}return a; } /*高精度a+b*/ bign add(bign a, bign b){bign c;int carry = 0; //進(jìn)位 for(int i=0; i<a.len||i<b.len; i++){ //以較長(zhǎng)的為界限 int temp = a.d[i] +b.d[i] + carry; //兩個(gè)對(duì)應(yīng)和進(jìn)位相加c.d[c.len++ ] = temp % 10; //個(gè)位數(shù)為該為結(jié)果carry = temp /10; //十位數(shù)為新的進(jìn)位 }if(carry!=0){ //如果最后進(jìn)位不為0,則直接賦給結(jié)果的最高位 c.d[c.len++] = carry;} return c; }/*輸出bign*/ void print(bign a){for(int i=a.len-1; i>=0; i--){printf("%d", a.d[i]);} }int main(){char str1[1000], str2[1000];scanf("%s %s", str1, str2);bign a = change(str1);bign b = change(str2);print(add(a, b));return 0; }減法、乘法、除法照葫蘆畫瓢即可,需要注意減法時(shí)需先比較兩個(gè)數(shù)的大小,如果被減數(shù)小于減數(shù),需要交換兩個(gè)變量,然后輸出負(fù)號(hào),再使用sub函數(shù)
總結(jié)
- 上一篇: 2020-2021年度第二届全国大学生算
- 下一篇: 日历和日期-算法