C语言实现大数计算器
C語(yǔ)言實(shí)現(xiàn)大數(shù)計(jì)算器
一、實(shí)驗(yàn)介紹
1.1 實(shí)驗(yàn)內(nèi)容
本實(shí)驗(yàn)通過(guò)使用C語(yǔ)言實(shí)現(xiàn)一個(gè)簡(jiǎn)易計(jì)算器,該計(jì)算器能夠進(jìn)行任意長(zhǎng)度的有符號(hào)整數(shù)的加、減、乘、除運(yùn)算。
1.2 實(shí)驗(yàn)知識(shí)點(diǎn)
- c語(yǔ)言大數(shù)加法實(shí)現(xiàn)
- c語(yǔ)言大數(shù)減法實(shí)現(xiàn)
- c語(yǔ)言大數(shù)乘法實(shí)現(xiàn)
- c語(yǔ)言大數(shù)除法實(shí)現(xiàn)
1.3 實(shí)驗(yàn)環(huán)境
- vim
- gcc 編譯器
- Xfce終端
1.4 適合人群
本課程適合已了解C語(yǔ)言基礎(chǔ)語(yǔ)法規(guī)則,并期望通過(guò)實(shí)際編程項(xiàng)目進(jìn)行演練,以提高C語(yǔ)言編程技巧的用戶進(jìn)行學(xué)習(xí)。
1.5 代碼獲取
你可以通過(guò)下面命令將代碼下載到實(shí)驗(yàn)樓環(huán)境中,作為參照對(duì)比進(jìn)行學(xué)習(xí)。
$ wget http://labfile.oss.aliyuncs.com/courses/750/calculator_sample.tar.gz $ tar xvf calculator_sample.tar.gz二、實(shí)驗(yàn)步驟
2.1 如何表示大數(shù)
由于C語(yǔ)言的基本數(shù)據(jù)類型在表示數(shù)字大小時(shí)都有一定的限制,所以要在C語(yǔ)言中表示一個(gè)大數(shù),有兩種方式:字符串和自行構(gòu)造數(shù)據(jù)結(jié)構(gòu)。
字符串表示,適合人解讀,但不適用于機(jī)器運(yùn)算
數(shù)據(jù)結(jié)構(gòu)表示,適用于機(jī)器運(yùn)算,但人對(duì)其進(jìn)行解讀比較困難
我們的設(shè)計(jì),綜合考慮上述兩種方式的優(yōu)缺點(diǎn),我們自行構(gòu)造數(shù)據(jù)用于表示大數(shù)以提供給機(jī)器進(jìn)行運(yùn)算,同時(shí)提供字符串與我們構(gòu)造的數(shù)據(jù)結(jié)構(gòu)進(jìn)行互轉(zhuǎn)的輔助性函數(shù):
// 大數(shù)數(shù)據(jù)結(jié)構(gòu) typedef struct bignumber_s{char sign; // 代表大數(shù)的符號(hào),1為負(fù)數(shù),0為正數(shù)int len; // 代表大數(shù)的位數(shù)char data[]; // 大數(shù)的數(shù)據(jù)內(nèi)容,data[0]代表個(gè)位,data[1]代表十位,data[2]代表百位.... } bignumber_s;// 構(gòu)造大數(shù)模板,len指向大數(shù)的數(shù)據(jù)位數(shù),sign表示該大數(shù)的符號(hào) bignumber_s *make_bignumber_temp(int len, int sign); // 從字符串構(gòu)造一個(gè)大數(shù) bignumber_s *make_bignumber_fromstr(const char *str); // 以字符串的形式打印輸出一個(gè)大數(shù) void print_bignumber(bignumber_s* b);在bignumber_s數(shù)據(jù)結(jié)構(gòu)的定義中,我們使用了C語(yǔ)言里一種稱為柔性數(shù)組的技巧,感興趣的同學(xué)可以自行研究。
下圖演示了我們的bignumber_s如何表示"-123"這個(gè)數(shù):
實(shí)現(xiàn)make_bignumber_temp函數(shù):
// 構(gòu)造大數(shù)模板,len指向大數(shù)的數(shù)據(jù)位數(shù),sign表示該大數(shù)的符號(hào) bignumber_s *make_bignumber_temp(int len, int sign) {// 分配bignumber_s及其所代表數(shù)據(jù) 所需的內(nèi)存bignumber_s *temp = malloc(sizeof(bignumber_s)+len);if (NULL == temp) {perror("Malloc");exit(-1);}temp->sign = sign;temp->len = len;memset(temp->data, 0, len);return temp; }實(shí)現(xiàn)make_bignumber_fromstr函數(shù):
// 從字符串構(gòu)造一個(gè)大數(shù) bignumber_s *make_bignumber_fromstr(const char *str) {// 處理負(fù)數(shù)字符串,即"-123"int sign = 0;if (str[0]=='-') {sign = 1;str++;}// 處理數(shù)字字符串冗余的0,即"00123" -> "123"const char * striped_str = strip_str(str);int len = strlen(striped_str);// 指定數(shù)據(jù)位長(zhǎng)度即符號(hào),創(chuàng)建一個(gè)大數(shù)模板bignumber_s *temp = make_bignumber_temp(len ,sign);// 將字符串?dāng)?shù)據(jù)填充進(jìn)模板中,完成大數(shù)創(chuàng)建fill_data_fromstr(temp, striped_str);return temp; } // 處理數(shù)字字符串冗余的0,即"00123" -> "123" const char *strip_str(const char *str) {int i = 0;int len = strlen(str);for (i=0; i<len-1&&str[i]=='0'; i++) ;return str+i; } // 將字符串?dāng)?shù)據(jù)填充進(jìn)模板中 void fill_data_fromstr(bignumber_s *n, const char *str) {int i = 0;int len = n->len;for (i=0; i<len; i++) {int d = str[len-1-i]-'0';if (d>=0 && d<=9) n->data[i] = d;else {fprintf(stderr, "Invalid Number:%s\n", str);exit(-1);}} }實(shí)現(xiàn)print_bignumber函數(shù):
// 以字符串的形式打印輸出一個(gè)大數(shù) void print_bignumber(bignumber_s* b) {int len = b->len;char *str = malloc(len+1);int i = 0;for (i=0; i<len; i++) {str[i] = b->data[len-i-1]+'0';}str[len] = '\0';fprintf(stdout,"%s%s\n", b->sign==1?"-":"", strip_str(str));free(str); }2.2 實(shí)現(xiàn)計(jì)算器的殼
我們的計(jì)算器最終編譯生成為一個(gè)名為calculator的可執(zhí)行程序,使用計(jì)算器的方法如下:
$ ./calculator 123 + 123 # 執(zhí)行加法運(yùn)算 $ ./calculator 123 - 123 # 執(zhí)行減法運(yùn)算 $ ./calculator 123 x 123 # 執(zhí)行乘法運(yùn)算 $ ./calculator 123 / 123 # 執(zhí)行除法運(yùn)算實(shí)現(xiàn)我們的main函數(shù):
void usage(const char *s) {fprintf(stderr, "Usage:%s number1 op(+-x/) number2.\n",s);exit(-1); }bignumber_s *calc_add(bignumber_s *a, bignumber_s *b) {// 實(shí)現(xiàn)加法 } bignumber_s *calc_sub(bignumber_s *a, bignumber_s *b) {// 實(shí)現(xiàn)減法 } bignumber_s *calc_mul(bignumber_s *a, bignumber_s *b) {// 實(shí)現(xiàn)乘法 } bignumber_s *calc_div(bignumber_s *a, bignumber_s *b) {// 實(shí)現(xiàn)除法 } int main(int argc, char *argv[]) {bignumber_s *a = make_bignumber_fromstr(argv[1]);bignumber_s *b = make_bignumber_fromstr(argv[3]);if (argc!=4) usage(argv[0]);if (0 == strcmp(argv[2],"+"))print_bignumber(calc_add(a,b));else if (0 == strcmp(argv[2],"-"))print_bignumber(calc_sub(a,b));else if (0 == strcmp(argv[2],"x"))print_bignumber(calc_mul(a,b));else if (0 == strcmp(argv[2],"/"))print_bignumber(calc_div(a,b));else usage(argv[0]);return 0; }2.3 實(shí)現(xiàn)無(wú)符號(hào)加減法
2.3.1 實(shí)現(xiàn)無(wú)符號(hào)加法
加法的實(shí)現(xiàn)比較簡(jiǎn)單,我們借鑒小學(xué)時(shí)學(xué)過(guò)的豎式計(jì)算過(guò)程的思路:
思路大致是:
實(shí)現(xiàn)無(wú)符號(hào)加法:
// 實(shí)現(xiàn)無(wú)符號(hào)加法,a和b為加數(shù),r為和 void add_impl(bignumber_s *a, bignumber_s *b, bignumber_s *r) {int i = 0;char carry = 0;int len = r->len;for (i=0; i<len; i++) {if (i<a->len)carry += a->data[i];if (i<b->len)carry += b->data[i];r->data[i] = carry%BASE;carry /= BASE;} }bignumber_s *add(bignumber_s *a, bignumber_s *b) {// n位數(shù)+m位數(shù),其和最大為max(n,m)+1位數(shù)int len = MAX(a->len, b->len) + 1;bignumber_s *result = make_bignumber_temp(len,a->sign);// add_impl(a,b,result);return result; }2.3.2 實(shí)現(xiàn)無(wú)符號(hào)減法
減法的實(shí)現(xiàn)與加法的實(shí)現(xiàn)思路相似,依舊請(qǐng)出的我們豎式計(jì)數(shù)法:
思路大致是:
實(shí)現(xiàn)無(wú)符號(hào)減法:
// 實(shí)現(xiàn)無(wú)符號(hào)減法,a-b , r為差 void sub_impl(bignumber_s *a, bignumber_s *b, bignumber_s *r) {int i=0;int borrow = 0;int len = r->len;int temp = 0;for (i=0; i<len; i++) {temp = a->data[i]+BASE-borrow-((i<b->len)?b->data[i]:0);r->data[i] = temp%BASE;borrow = 1-temp/BASE;} }bignumber_s *sub(bignumber_s *a, bignumber_s *b) {int len = a->len;bignumber_s *result = make_bignumber_temp(len,0);sub_impl(a,b,result);return result; }2.3.3 大數(shù)計(jì)算器v1版本
大數(shù)計(jì)算器v1版本:
/* * file name : calculatorv1.c * desp : calculator version 1 */ // 大數(shù)數(shù)據(jù)結(jié)構(gòu) typedef struct bignumber_s{char sign; // 代表大數(shù)的符號(hào),1為負(fù)數(shù),0為正數(shù)int len; // 代表大數(shù)的位數(shù)char data[]; // 大數(shù)的數(shù)據(jù)內(nèi)容,data[0]代表個(gè)位,data[1]代表十位,data[2]代表百位.... } bignumber_s;// 構(gòu)造大數(shù)模板,len指向大數(shù)的數(shù)據(jù)位數(shù),sign表示該大數(shù)的符號(hào) bignumber_s *make_bignumber_temp(int len, int sign) {// 分配bignumber_s及其所代表數(shù)據(jù) 所需的內(nèi)存bignumber_s *temp = malloc(sizeof(bignumber_s)+len);if (NULL == temp) {perror("Malloc");exit(-1);}temp->sign = sign;temp->len = len;memset(temp->data, 0, len);return temp; }// 處理數(shù)字字符串冗余的0,即"00123" -> "123" const char *strip_str(const char *str) {int i = 0;int len = strlen(str);for (i=0; i<len-1&&str[i]=='0'; i++) ;return str+i; } // 將字符串?dāng)?shù)據(jù)填充進(jìn)模板中 void fill_data_fromstr(bignumber_s *n, const char *str) {int i = 0;int len = n->len;for (i=0; i<len; i++) {int d = str[len-1-i]-'0';if (d>=0 && d<=9) n->data[i] = d;else {fprintf(stderr, "Invalid Number:%s\n", str);exit(-1);}} } // 從字符串構(gòu)造一個(gè)大數(shù) bignumber_s *make_bignumber_fromstr(const char *str) {// 處理負(fù)數(shù)字符串,即"-123"int sign = 0;if (str[0]=='-') {sign = 1;str++;}// 處理數(shù)字字符串冗余的0,即"00123" -> "123"const char * striped_str = strip_str(str);int len = strlen(striped_str);// 指定數(shù)據(jù)位長(zhǎng)度即符號(hào),創(chuàng)建一個(gè)大數(shù)模板bignumber_s *temp = make_bignumber_temp(len ,sign);// 將字符串?dāng)?shù)據(jù)填充進(jìn)模板中,完成大數(shù)創(chuàng)建fill_data_fromstr(temp, striped_str);return temp; }// 以字符串的形式打印輸出一個(gè)大數(shù) void print_bignumber(bignumber_s* b) {int len = b->len;char *str = malloc(len+1);int i = 0;for (i=0; i<len; i++) {str[i] = b->data[len-i-1]+'0';}str[len] = '\0';fprintf(stdout,"%s%s\n", b->sign==1?"-":"", strip_str(str));free(str); }void usage(const char *s) {fprintf(stderr, "Usage:%s number1 +-x/ number2.\n",s);exit(-1); }// 實(shí)現(xiàn)無(wú)符號(hào)加法,a和b為加數(shù),r為和 void add_impl(bignumber_s *a, bignumber_s *b, bignumber_s *r) {int i = 0;char carry = 0;int len = r->len;for (i=0; i<len; i++) {if (i<a->len)carry += a->data[i];if (i<b->len)carry += b->data[i];r->data[i] = carry%BASE;carry /= BASE;} }bignumber_s *calc_add(bignumber_s *a, bignumber_s *b) {// n位數(shù)+m位數(shù),其和最大為max(n,m)+1位數(shù)int len = MAX(a->len, b->len) + 1;bignumber_s *result = make_bignumber_temp(len, 0);// add_impl(a,b,result);return result; }// 實(shí)現(xiàn)無(wú)符號(hào)減法,a-b , r為差 void sub_impl(bignumber_s *a, bignumber_s *b, bignumber_s *r) {int i=0;int borrow = 0;int len = r->len;int temp = 0;for (i=0; i<len; i++) {temp = a->data[i]+BASE-borrow-((i<b->len)?b->data[i]:0);r->data[i] = temp%BASE;borrow = temp/BASE?0:1;} }bignumber_s *calc_sub(bignumber_s *a, bignumber_s *b) {int len = a->len;bignumber_s *result = make_bignumber_temp(len,0);sub_impl(a,b,result);return result; }bignumber_s *calc_mul(bignumber_s *a, bignumber_s *b) {// 實(shí)現(xiàn)乘法return NULL; } bignumber_s *calc_div(bignumber_s *a, bignumber_s *b) {// 實(shí)現(xiàn)除法return NULL; } int main(int argc, char *argv[]) {bignumber_s *a = make_bignumber_fromstr(argv[1]);bignumber_s *b = make_bignumber_fromstr(argv[3]);if (argc!=4) usage(argv[0]);if (0 == strcmp(argv[2],"+"))print_bignumber(calc_add(a,b));else if (0 == strcmp(argv[2],"-"))print_bignumber(calc_sub(a,b));else if (0 == strcmp(argv[2],"x"))print_bignumber(calc_mul(a,b));else if (0 == strcmp(argv[2],"/"))print_bignumber(calc_div(a,b));else usage(argv[0]);return 0; }2.3.4 演示
編譯命令:
$ gcc -o calculatorv1 calculatorv1.c結(jié)果演示:?
可以使用python交互界面驗(yàn)證我們的計(jì)算結(jié)果:
2.4 實(shí)現(xiàn)有符號(hào)加減法
2.4.1 有符號(hào)加法
先來(lái)看有符號(hào)的加法,假設(shè)有兩個(gè)數(shù)A和B,有符號(hào)加法分以下幾種情況:
// 情況一:A > 0 并且 B > 0 A + B --> |A| + |B| (|A|表示求A的絕對(duì)值,下同) // 情況二:A > 0 并且 B < 0 A + B --> |A| - |B| // 情況三:A < 0 并且 B > 0 A + B --> |B| - |A| // 情況四:A < 0 并且 B < 0 A + B --> -(|B| + |A|) (此處-表示取負(fù)值)情況一和情況四可以用第2節(jié)的無(wú)符號(hào)加法求解,情況四在用加法求值后再取負(fù)值;情況二和情況三轉(zhuǎn)化為有符號(hào)減法操作。
因此我們的加法函數(shù)可以這么實(shí)現(xiàn):
bignumber_s *calc_add(bignumber_s *a, bignumber_s *b) {// 情況一和情況四if (a->sign==b->sign) {// n位數(shù)+m位數(shù),其和最大為max(n,m)+1位數(shù)int len = MAX(a->len, b->len) + 1;bignumber_s *result = make_bignumber_temp(len,a->sign);add_impl(a,b,result);return result;} else if (a->sign == 0 && b->sign == 1) {//情況二b->sign = 0; //b數(shù)去絕對(duì)值return calc_sub(a,b);} else if (a->sign == 1 && b->sign == 0) {//情況三a->sign = 0; //a數(shù)去絕對(duì)值return calc_sub(b,a);} }2.4.2 有符號(hào)減法
接下來(lái)看有符號(hào)的減法,假設(shè)有兩個(gè)數(shù)A和B,有符號(hào)減法分以下幾種情況:
// 情況一:A > 0 并且 B > 0 A - B --> |A| - |B| (|A|表示求A的絕對(duì)值,下同) // 情況二:A > 0 并且 B < 0 A - B --> |A| + |B| // 情況三:A < 0 并且 B > 0 A - B --> -(|A| + |B|) (此處-表示取負(fù)值) // 情況四:A < 0 并且 B < 0 A - B --> |B| - |A|情況二和情況三可以轉(zhuǎn)化為第2節(jié)的無(wú)符號(hào)加法求解,情況三在用加法求值后再取負(fù)值;
情況一,當(dāng)被減數(shù)大于減數(shù)時(shí),結(jié)果為正數(shù),可以直接用第2節(jié)的減法實(shí)現(xiàn)求解;
當(dāng)被減數(shù)小于減數(shù)時(shí),結(jié)果為負(fù)數(shù),即:
// A < B, A>=0 且B>=0 時(shí) A - B ---> -(B-A)情況四,將減數(shù)和被減數(shù)調(diào)換就成了情況一了。
我們需要先實(shí)現(xiàn)一個(gè)用以判斷兩個(gè)大數(shù)大小的輔助函數(shù),用以判斷被減數(shù)和減數(shù)的大小:
int valid_len(bignumber_s *a) {int len = a->len;int i = len-1;for (i=len-1; i>=0; i--) {if (a->data[i]==0) len--;else break;}return len; } // 判斷兩個(gè)大數(shù)的大小 // a > b 返回1 ,a<b 返回 -1 , a==b 返回0 int cmp(bignumber_s *a, bignumber_s *b) {if (a->sign==0&&b->sign==1) return 1;if (a->sign==1&&b->sign==0) return -1;int sign = a->sign;int alen = valid_len(a);int blen = valid_len(b);if (alen>blen) return (sign==1?-1:1);else if (alen<blen) return (sign==1?1:-1);else {int i = 0;int len = alen;for (i=len-1; i>=0; i--) {if (a->data[i]>b->data[i])return (sign==1?-1:1);else if (a->data[i]<b->data[i]) return (sign==1?1:-1);}return 0;} }有符號(hào)的減法實(shí)現(xiàn)如下:
bignumber_s *sub(bignumber_s *a, bignumber_s *b) {// 情況一if(a->sign==0 && b->sign==0) {if (cmp(a,b)>=0) { // 被減數(shù)大于等于減數(shù),即差大于等于0時(shí)int len = a->len;bignumber_s *result = make_bignumber_temp(len,0);sub_impl(a,b,result);return result;} else { // 被減數(shù)小于減數(shù),即差小于0時(shí)int len = b->len;bignumber_s *result = make_bignumber_temp(len,1);sub_impl(b,a,result);return result;}} else if (a->sign==1 && b->sign==1) { //情況四b->sign=0; a->sign=0;return sub(b,a); //調(diào)換減數(shù)和被減數(shù),變成情況一}else if (a->sign==0 && b->sign==1) { // 情況二b->sign=0;bignumber_s *result = add(a,b);result->sign = 0;return result; } else if (a->sign==1 && b->sign==0) { // 情況三a->sign=0;bignumber_s *result = add(a,b);result->sign = 1;return result; } }2.4.3 大數(shù)計(jì)算器v2版本
完整代碼如下(calculatorv2.c):
/* * file name : calculatorv2.c * desp : calculator version 2 */ // 大數(shù)數(shù)據(jù)結(jié)構(gòu) typedef struct bignumber_s{char sign; // 代表大數(shù)的符號(hào),1為負(fù)數(shù),0為正數(shù)int len; // 代表大數(shù)的位數(shù)char data[]; // 大數(shù)的數(shù)據(jù)內(nèi)容,data[0]代表個(gè)位,data[1]代表十位,data[2]代表百位.... } bignumber_s; bignumber_s *calc_add(bignumber_s *a, bignumber_s *b); bignumber_s *calc_sub(bignumber_s *a, bignumber_s *b);// 構(gòu)造大數(shù)模板,len指向大數(shù)的數(shù)據(jù)位數(shù),sign表示該大數(shù)的符號(hào) bignumber_s *make_bignumber_temp(int len, int sign) {// 分配bignumber_s及其所代表數(shù)據(jù) 所需的內(nèi)存bignumber_s *temp = malloc(sizeof(bignumber_s)+len);if (NULL == temp) {perror("Malloc");exit(-1);}temp->sign = sign;temp->len = len;memset(temp->data, 0, len);return temp; }// 處理數(shù)字字符串冗余的0,即"00123" -> "123" const char *strip_str(const char *str) {int i = 0;int len = strlen(str);for (i=0; i<len-1&&str[i]=='0'; i++) ;return str+i; } // 將字符串?dāng)?shù)據(jù)填充進(jìn)模板中 void fill_data_fromstr(bignumber_s *n, const char *str) {int i = 0;int len = n->len;for (i=0; i<len; i++) {int d = str[len-1-i]-'0';if (d>=0 && d<=9) n->data[i] = d;else {fprintf(stderr, "Invalid Number:%s\n", str);exit(-1);}} } // 從字符串構(gòu)造一個(gè)大數(shù) bignumber_s *make_bignumber_fromstr(const char *str) {// 處理負(fù)數(shù)字符串,即"-123"int sign = 0;if (str[0]=='-') {sign = 1;str++;}// 處理數(shù)字字符串冗余的0,即"00123" -> "123"const char * striped_str = strip_str(str);int len = strlen(striped_str);// 指定數(shù)據(jù)位長(zhǎng)度即符號(hào),創(chuàng)建一個(gè)大數(shù)模板bignumber_s *temp = make_bignumber_temp(len ,sign);// 將字符串?dāng)?shù)據(jù)填充進(jìn)模板中,完成大數(shù)創(chuàng)建fill_data_fromstr(temp, striped_str);return temp; }// 以字符串的形式打印輸出一個(gè)大數(shù) void print_bignumber(bignumber_s* b) {int len = b->len;char *str = malloc(len+1);int i = 0;for (i=0; i<len; i++) {str[i] = b->data[len-i-1]+'0';}str[len] = '\0';fprintf(stdout,"%s%s\n", b->sign==1?"-":"", strip_str(str));free(str); }void usage(const char *s) {fprintf(stderr, "Usage:%s number1 +-x/ number2.\n",s);exit(-1); }// 實(shí)現(xiàn)無(wú)符號(hào)加法,a和b為加數(shù),r為和 void add_impl(bignumber_s *a, bignumber_s *b, bignumber_s *r) {int i = 0;char carry = 0;int len = r->len;for (i=0; i<len; i++) {if (i<a->len)carry += a->data[i];if (i<b->len)carry += b->data[i];r->data[i] = carry%BASE;carry /= BASE;} }bignumber_s *calc_add(bignumber_s *a, bignumber_s *b) {// 情況一和情況四if (a->sign==b->sign) {// n位數(shù)+m位數(shù),其和最大為max(n,m)+1位數(shù)int len = MAX(a->len, b->len) + 1;bignumber_s *result = make_bignumber_temp(len,a->sign);add_impl(a,b,result);return result;} else if (a->sign == 0 && b->sign == 1) {//情況二b->sign = 0; //b數(shù)去絕對(duì)值return calc_sub(a,b);} else if (a->sign == 1 && b->sign == 0) {//情況三a->sign = 0; //a數(shù)去絕對(duì)值return calc_sub(b,a);} }// 實(shí)現(xiàn)無(wú)符號(hào)減法,a-b , r為差 void sub_impl(bignumber_s *a, bignumber_s *b, bignumber_s *r) {int i=0;int borrow = 0;int len = r->len;int temp = 0;for (i=0; i<len; i++) {temp = a->data[i]+BASE-borrow-((i<b->len)?b->data[i]:0);r->data[i] = temp%BASE;borrow = temp/BASE?0:1;} }int valid_len(bignumber_s *a) {int len = a->len;int i = len-1;for (i=len-1; i>=0; i--) {if (a->data[i]==0) len--;else break;}return len; } // 判斷兩個(gè)大數(shù)的大小 // a > b 返回1 ,a<b 返回 -1 , a==b 返回0 int cmp(bignumber_s *a, bignumber_s *b) {if (a->sign==0&&b->sign==1) return 1;if (a->sign==1&&b->sign==0) return -1;int sign = a->sign;int alen = valid_len(a);int blen = valid_len(b);if (alen>blen) return (sign==1?-1:1);else if (alen<blen) return (sign==1?1:-1);else {int i = 0;int len = alen;for (i=len-1; i>=0; i--) {if (a->data[i]>b->data[i])return (sign==1?-1:1);else if (a->data[i]<b->data[i]) return (sign==1?1:-1);}return 0;} }bignumber_s *calc_sub(bignumber_s *a, bignumber_s *b) {// 情況一if(a->sign==0 && b->sign==0) {if (cmp(a,b)>=0) { // 被減數(shù)大于等于減數(shù),即差大于等于0時(shí)int len = a->len;bignumber_s *result = make_bignumber_temp(len,0);sub_impl(a,b,result);return result;} else { // 被減數(shù)小于減數(shù),即差小于0時(shí)int len = b->len;bignumber_s *result = make_bignumber_temp(len,1);sub_impl(b,a,result);return result;}} else if (a->sign==1 && b->sign==1) { //情況四b->sign=0; a->sign=0;return calc_sub(b,a); //調(diào)換減數(shù)和被減數(shù),變成情況一}else if (a->sign==0 && b->sign==1) { // 情況二b->sign=0;bignumber_s *result = calc_add(a,b);result->sign = 0;return result; } else if (a->sign==1 && b->sign==0) { // 情況三a->sign=0;bignumber_s *result = calc_add(a,b);result->sign = 1;return result; } }bignumber_s *calc_mul(bignumber_s *a, bignumber_s *b) {// 實(shí)現(xiàn)乘法return NULL; } bignumber_s *calc_div(bignumber_s *a, bignumber_s *b) {// 實(shí)現(xiàn)除法return NULL; } int main(int argc, char *argv[]) {bignumber_s *a = make_bignumber_fromstr(argv[1]);bignumber_s *b = make_bignumber_fromstr(argv[3]);if (argc!=4) usage(argv[0]);if (0 == strcmp(argv[2],"+"))print_bignumber(calc_add(a,b));else if (0 == strcmp(argv[2],"-"))print_bignumber(calc_sub(a,b));else if (0 == strcmp(argv[2],"x"))print_bignumber(calc_mul(a,b));else if (0 == strcmp(argv[2],"/"))print_bignumber(calc_div(a,b));else usage(argv[0]);return 0; }2.4.4 演示
編譯命令:
$ gcc -o calculatorv2 calculatorv2.c結(jié)果演示:
2.5 實(shí)現(xiàn)乘法
2.5.1 正數(shù)乘法實(shí)現(xiàn)
乘法的實(shí)現(xiàn)稍微比加減法復(fù)雜一些,但是和加減法是同樣的實(shí)現(xiàn)原理。
依舊搬出我們的豎式計(jì)算法:
假設(shè)x[0...n]乘以y[0...m],其中0代表x數(shù)的個(gè)位,n代表x數(shù)的最高位,假設(shè)用x代表上述的145這個(gè)數(shù)。那么x[0]就是5, x[1]就是4, x[1]就是1; 類似的y代表12, 則y[0]為2, y[1]為1。
乘法的實(shí)現(xiàn)思路:
這里有兩點(diǎn)需要注意:
代碼實(shí)現(xiàn)如下:
void mul_impl(bignumber_s *x, bignumber_s *y, bignumber_s *z) {int n = x->len;int m = y->len;int i = 0;int j = 0;int carry = 0;for (i=0; i<m; i++) {// y的每一位乘以x,即計(jì)算y[i] * x[0...n] 并累加到z[i...i+n]中for (j=0; j<n; j++) {carry += y->data[i]*x->data[j] + z->data[i+j];z->data[i+j] = carry%BASE;carry /= BASE;}// 將剩余的進(jìn)位,繼續(xù)在z[i+n...n+m]中累加,從而完成y[i]乘以x[0...n]其積累加到z[i...m+n]中for (; j+i<n+m; j++) {carry += z->data[i+j];z->data[i+j] = carry % BASE;carry /= BASE;}} }bignumber_s *calc_mul(bignumber_s *a, bignumber_s *b) {int len = a->len + b->len;bignumber_s *result = make_bignumber_temp(len,0);mul_impl(a,b,result);return result; }2.5.2 有符號(hào)乘法
有符號(hào)的 乘法可以轉(zhuǎn)化為無(wú)符號(hào)的乘法,分以下兩種情況:
// 情況一 (A>0 && B>0) 或者 (A>0 && B>0) A x B --> |A| x |B| // 情況二 (A>0 && B<0) 或者 (A<0 && B>0) A x B --> -(|A| x |B|)代碼實(shí)現(xiàn)如下:
bignumber_s *calc_mul(bignumber_s *a, bignumber_s *b) {int len = a->len + b->len;bignumber_s *result = make_bignumber_temp(len,a->sign==b->sign?0:1); //a->sign==b->sign為情況一,否則為情況二。mul_impl(a,b,result);return result; }2.5.3大數(shù)計(jì)算器v3版本
/* * file name : calculatorv3.c * desp : calculator version 3 */ // 大數(shù)數(shù)據(jù)結(jié)構(gòu) typedef struct bignumber_s{char sign; // 代表大數(shù)的符號(hào),1為負(fù)數(shù),0為正數(shù)int len; // 代表大數(shù)的位數(shù)char data[]; // 大數(shù)的數(shù)據(jù)內(nèi)容,data[0]代表個(gè)位,data[1]代表十位,data[2]代表百位.... } bignumber_s;bignumber_s *calc_add(bignumber_s *a, bignumber_s *b); bignumber_s *calc_sub(bignumber_s *a, bignumber_s *b);// 構(gòu)造大數(shù)模板,len指向大數(shù)的數(shù)據(jù)位數(shù),sign表示該大數(shù)的符號(hào) bignumber_s *make_bignumber_temp(int len, int sign) {// 分配bignumber_s及其所代表數(shù)據(jù) 所需的內(nèi)存bignumber_s *temp = malloc(sizeof(bignumber_s)+len);if (NULL == temp) {perror("Malloc");exit(-1);}temp->sign = sign;temp->len = len;memset(temp->data, 0, len);return temp; }// 處理數(shù)字字符串冗余的0,即"00123" -> "123" const char *strip_str(const char *str) {int i = 0;int len = strlen(str);for (i=0; i<len-1&&str[i]=='0'; i++) ;return str+i; } // 將字符串?dāng)?shù)據(jù)填充進(jìn)模板中 void fill_data_fromstr(bignumber_s *n, const char *str) {int i = 0;int len = n->len;for (i=0; i<len; i++) {int d = str[len-1-i]-'0';if (d>=0 && d<=9) n->data[i] = d;else {fprintf(stderr, "Invalid Number:%s\n", str);exit(-1);}} } // 從字符串構(gòu)造一個(gè)大數(shù) bignumber_s *make_bignumber_fromstr(const char *str) {// 處理負(fù)數(shù)字符串,即"-123"int sign = 0;if (str[0]=='-') {sign = 1;str++;}// 處理數(shù)字字符串冗余的0,即"00123" -> "123"const char * striped_str = strip_str(str);int len = strlen(striped_str);// 指定數(shù)據(jù)位長(zhǎng)度即符號(hào),創(chuàng)建一個(gè)大數(shù)模板bignumber_s *temp = make_bignumber_temp(len ,sign);// 將字符串?dāng)?shù)據(jù)填充進(jìn)模板中,完成大數(shù)創(chuàng)建fill_data_fromstr(temp, striped_str);return temp; }// 以字符串的形式打印輸出一個(gè)大數(shù) void print_bignumber(bignumber_s* b) {int len = b->len;char *str = malloc(len+1);int i = 0;for (i=0; i<len; i++) {str[i] = b->data[len-i-1]+'0';}str[len] = '\0';fprintf(stdout,"%s%s\n", b->sign==1?"-":"", strip_str(str));free(str); }void usage(const char *s) {fprintf(stderr, "Usage:%s number1 +-x/ number2.\n",s);exit(-1); }// 實(shí)現(xiàn)無(wú)符號(hào)加法,a和b為加數(shù),r為和 void add_impl(bignumber_s *a, bignumber_s *b, bignumber_s *r) {int i = 0;char carry = 0;int len = r->len;for (i=0; i<len; i++) {if (i<a->len)carry += a->data[i];if (i<b->len)carry += b->data[i];r->data[i] = carry%BASE;carry /= BASE;} }bignumber_s *calc_add(bignumber_s *a, bignumber_s *b) {// 情況一和情況四if (a->sign==b->sign) {// n位數(shù)+m位數(shù),其和最大為max(n,m)+1位數(shù)int len = MAX(a->len, b->len) + 1;bignumber_s *result = make_bignumber_temp(len,a->sign);add_impl(a,b,result);return result;} else if (a->sign == 0 && b->sign == 1) {//情況二b->sign = 0; //b數(shù)去絕對(duì)值return calc_sub(a,b);} else if (a->sign == 1 && b->sign == 0) {//情況三a->sign = 0; //a數(shù)去絕對(duì)值return calc_sub(b,a);} }// 實(shí)現(xiàn)無(wú)符號(hào)減法,a-b , r為差 void sub_impl(bignumber_s *a, bignumber_s *b, bignumber_s *r) {int i=0;int borrow = 0;int len = r->len;int temp = 0;for (i=0; i<len; i++) {temp = a->data[i]+BASE-borrow-((i<b->len)?b->data[i]:0);r->data[i] = temp%BASE;borrow = temp/BASE?0:1;} }int valid_len(bignumber_s *a) {int len = a->len;int i = len-1;for (i=len-1; i>=0; i--) {if (a->data[i]==0) len--;else break;}return len; } // 判斷兩個(gè)大數(shù)的大小 // a > b 返回1 ,a<b 返回 -1 , a==b 返回0 int cmp(bignumber_s *a, bignumber_s *b) {if (a->sign==0&&b->sign==1) return 1;if (a->sign==1&&b->sign==0) return -1;int sign = a->sign;int alen = valid_len(a);int blen = valid_len(b);if (alen>blen) return (sign==1?-1:1);else if (alen<blen) return (sign==1?1:-1);else {int i = 0;int len = alen;for (i=len-1; i>=0; i--) {if (a->data[i]>b->data[i])return (sign==1?-1:1);else if (a->data[i]<b->data[i]) return (sign==1?1:-1);}return 0;} }bignumber_s *calc_sub(bignumber_s *a, bignumber_s *b) {// 情況一if(a->sign==0 && b->sign==0) {if (cmp(a,b)>=0) { // 被減數(shù)大于等于減數(shù),即差大于等于0時(shí)int len = a->len;bignumber_s *result = make_bignumber_temp(len,0);sub_impl(a,b,result);return result;} else { // 被減數(shù)小于減數(shù),即差小于0時(shí)int len = b->len;bignumber_s *result = make_bignumber_temp(len,1);sub_impl(b,a,result);return result;}} else if (a->sign==1 && b->sign==1) { //情況四b->sign=0; a->sign=0;return calc_sub(b,a); //調(diào)換減數(shù)和被減數(shù),變成情況一}else if (a->sign==0 && b->sign==1) { // 情況二b->sign=0;bignumber_s *result = calc_add(a,b);result->sign = 0;return result; } else if (a->sign==1 && b->sign==0) { // 情況三a->sign=0;bignumber_s *result = calc_add(a,b);result->sign = 1;return result; } }// 實(shí)現(xiàn)無(wú)符號(hào)乘法,axb , z為積 void mul_impl(bignumber_s *x, bignumber_s *y, bignumber_s *z) {int n = x->len;int m = y->len;int i = 0;int j = 0;int carry = 0;for (i=0; i<m; i++) {// y的每一位乘以x,即計(jì)算y[i] * x[0...n] 并累加到z[i...i+n]中for (j=0; j<n; j++) {carry += y->data[i]*x->data[j] + z->data[i+j];z->data[i+j] = carry%BASE;carry /= BASE;}// 將剩余的進(jìn)位,繼續(xù)在z[i+n...n+m]中累加,從而完成y[i]乘以x[0...n]其積累加到z[i...m+n]中for (; j+i<n+m; j++) {carry += z->data[i+j];z->data[i+j] = carry % BASE;carry /= BASE;}} }bignumber_s *calc_mul(bignumber_s *a, bignumber_s *b) {int len = a->len + b->len;bignumber_s *result = make_bignumber_temp(len,a->sign==b->sign?0:1); //a->sign==b->sign為情況一,否則為情況二。mul_impl(a,b,result);return result; }bignumber_s *calc_div(bignumber_s *a, bignumber_s *b) {// 實(shí)現(xiàn)除法return NULL; } int main(int argc, char *argv[]) {bignumber_s *a = make_bignumber_fromstr(argv[1]);bignumber_s *b = make_bignumber_fromstr(argv[3]);if (argc!=4) usage(argv[0]);if (0 == strcmp(argv[2],"+"))print_bignumber(calc_add(a,b));else if (0 == strcmp(argv[2],"-"))print_bignumber(calc_sub(a,b));else if (0 == strcmp(argv[2],"x"))print_bignumber(calc_mul(a,b));else if (0 == strcmp(argv[2],"/"))print_bignumber(calc_div(a,b));else usage(argv[0]);return 0; }2.5.4 演示
編譯命令:
$ gcc -o calculatorv3 calculatorv3.c結(jié)果演示:
2.6 實(shí)現(xiàn)除法
2.6.1 除法實(shí)現(xiàn)
除法的實(shí)現(xiàn),我們直接轉(zhuǎn)化為減法,大致思路如下:
這種實(shí)現(xiàn)方法,在某種情況下效率會(huì)非常低,但是實(shí)現(xiàn)起來(lái)比較簡(jiǎn)單。
有符號(hào)的除法,其處理更乘法是一致的。
除法實(shí)現(xiàn)代碼如下:
// 大數(shù)加一操作 void plusone(bignumber_s *a) {int len = a->len ;int i;int carry = 1;for (i=0; i<len; i++) {carry += a->data[i];a->data[i] = carry%BASE;carry /= BASE;} } // 大數(shù)除法實(shí)現(xiàn) bignumber_s *calc_div(bignumber_s *a, bignumber_s *b) {bignumber_s *zero = make_bignumber_temp(1,0);if (cmp(b,zero)==0) {// 除數(shù)為0 報(bào)錯(cuò)fprintf(stderr,"Integer division by zero\n");exit(-1);}else if (cmp(a,zero)==0) { // 被除數(shù)為0 ,結(jié)果為0return zero;}int len = a->len;bignumber_s *result = make_bignumber_temp(len,a->sign==b->sign?0:1);a->sign = 0;b->sign = 0;bignumber_s *temp = make_bignumber_temp(len, 0);bignumber_s *aa = a;while(1) {if (cmp(aa, b)>=0) {sub_impl(aa, b, temp);plusone(result);aa = temp;} else {free(temp);return result;}} }2.6.2 大數(shù)計(jì)算器v4版本
/* * file name : calculatorv4.c * desp : calculator version 4 */ // 大數(shù)數(shù)據(jù)結(jié)構(gòu) typedef struct bignumber_s{char sign; // 代表大數(shù)的符號(hào),1為負(fù)數(shù),0為正數(shù)int len; // 代表大數(shù)的位數(shù)char data[]; // 大數(shù)的數(shù)據(jù)內(nèi)容,data[0]代表個(gè)位,data[1]代表十位,data[2]代表百位.... } bignumber_s;bignumber_s *calc_add(bignumber_s *a, bignumber_s *b); bignumber_s *calc_sub(bignumber_s *a, bignumber_s *b);// 構(gòu)造大數(shù)模板,len指向大數(shù)的數(shù)據(jù)位數(shù),sign表示該大數(shù)的符號(hào) bignumber_s *make_bignumber_temp(int len, int sign) {// 分配bignumber_s及其所代表數(shù)據(jù) 所需的內(nèi)存bignumber_s *temp = malloc(sizeof(bignumber_s)+len);if (NULL == temp) {perror("Malloc");exit(-1);}temp->sign = sign;temp->len = len;memset(temp->data, 0, len);return temp; }// 處理數(shù)字字符串冗余的0,即"00123" -> "123" const char *strip_str(const char *str) {int i = 0;int len = strlen(str);for (i=0; i<len-1&&str[i]=='0'; i++) ;return str+i; } // 將字符串?dāng)?shù)據(jù)填充進(jìn)模板中 void fill_data_fromstr(bignumber_s *n, const char *str) {int i = 0;int len = n->len;for (i=0; i<len; i++) {int d = str[len-1-i]-'0';if (d>=0 && d<=9) n->data[i] = d;else {fprintf(stderr, "Invalid Number:%s\n", str);exit(-1);}} } // 從字符串構(gòu)造一個(gè)大數(shù) bignumber_s *make_bignumber_fromstr(const char *str) {// 處理負(fù)數(shù)字符串,即"-123"int sign = 0;if (str[0]=='-') {sign = 1;str++;}// 處理數(shù)字字符串冗余的0,即"00123" -> "123"const char * striped_str = strip_str(str);int len = strlen(striped_str);// 指定數(shù)據(jù)位長(zhǎng)度即符號(hào),創(chuàng)建一個(gè)大數(shù)模板bignumber_s *temp = make_bignumber_temp(len ,sign);// 將字符串?dāng)?shù)據(jù)填充進(jìn)模板中,完成大數(shù)創(chuàng)建fill_data_fromstr(temp, striped_str);return temp; }// 以字符串的形式打印輸出一個(gè)大數(shù) void print_bignumber(bignumber_s* b) {int len = b->len;char *str = malloc(len+1);int i = 0;for (i=0; i<len; i++) {str[i] = b->data[len-i-1]+'0';}str[len] = '\0';fprintf(stdout,"%s%s\n", b->sign==1?"-":"", strip_str(str));free(str); }void usage(const char *s) {fprintf(stderr, "Usage:%s number1 +-x/ number2.\n",s);exit(-1); }// 實(shí)現(xiàn)無(wú)符號(hào)加法,a和b為加數(shù),r為和 void add_impl(bignumber_s *a, bignumber_s *b, bignumber_s *r) {int i = 0;char carry = 0;int len = r->len;for (i=0; i<len; i++) {if (i<a->len)carry += a->data[i];if (i<b->len)carry += b->data[i];r->data[i] = carry%BASE;carry /= BASE;} }bignumber_s *calc_add(bignumber_s *a, bignumber_s *b) {// 情況一和情況四if (a->sign==b->sign) {// n位數(shù)+m位數(shù),其和最大為max(n,m)+1位數(shù)int len = MAX(a->len, b->len) + 1;bignumber_s *result = make_bignumber_temp(len,a->sign);add_impl(a,b,result);return result;} else if (a->sign == 0 && b->sign == 1) {//情況二b->sign = 0; //b數(shù)去絕對(duì)值return calc_sub(a,b);} else if (a->sign == 1 && b->sign == 0) {//情況三a->sign = 0; //a數(shù)去絕對(duì)值return calc_sub(b,a);} }// 實(shí)現(xiàn)無(wú)符號(hào)減法,a-b , r為差 void sub_impl(bignumber_s *a, bignumber_s *b, bignumber_s *r) {int i=0;int borrow = 0;int len = r->len;int temp = 0;for (i=0; i<len; i++) {temp = a->data[i]+BASE-borrow-((i<b->len)?b->data[i]:0);r->data[i] = temp%BASE;borrow = temp/BASE?0:1;} }int valid_len(bignumber_s *a) {int len = a->len;int i = len-1;for (i=len-1; i>=0; i--) {if (a->data[i]==0) len--;else break;}return len; } // 判斷兩個(gè)大數(shù)的大小 // a > b 返回1 ,a<b 返回 -1 , a==b 返回0 int cmp(bignumber_s *a, bignumber_s *b) {if (a->sign==0&&b->sign==1) return 1;if (a->sign==1&&b->sign==0) return -1;int sign = a->sign;int alen = valid_len(a);int blen = valid_len(b);if (alen>blen) return (sign==1?-1:1);else if (alen<blen) return (sign==1?1:-1);else {int i = 0;int len = alen;for (i=len-1; i>=0; i--) {if (a->data[i]>b->data[i])return (sign==1?-1:1);else if (a->data[i]<b->data[i]) return (sign==1?1:-1);}return 0;} }bignumber_s *calc_sub(bignumber_s *a, bignumber_s *b) {// 情況一if(a->sign==0 && b->sign==0) {if (cmp(a,b)>=0) { // 被減數(shù)大于等于減數(shù),即差大于等于0時(shí)int len = a->len;bignumber_s *result = make_bignumber_temp(len,0);sub_impl(a,b,result);return result;} else { // 被減數(shù)小于減數(shù),即差小于0時(shí)int len = b->len;bignumber_s *result = make_bignumber_temp(len,1);sub_impl(b,a,result);return result;}} else if (a->sign==1 && b->sign==1) { //情況四b->sign=0; a->sign=0;return calc_sub(b,a); //調(diào)換減數(shù)和被減數(shù),變成情況一}else if (a->sign==0 && b->sign==1) { // 情況二b->sign=0;bignumber_s *result = calc_add(a,b);result->sign = 0;return result; } else if (a->sign==1 && b->sign==0) { // 情況三a->sign=0;bignumber_s *result = calc_add(a,b);result->sign = 1;return result; } }// 實(shí)現(xiàn)無(wú)符號(hào)乘法,x * y , z為積 void mul_impl(bignumber_s *x, bignumber_s *y, bignumber_s *z) {int n = x->len;int m = y->len;int i = 0;int j = 0;int carry = 0;for (i=0; i<m; i++) {// y的每一位乘以x,即計(jì)算y[i] * x[0...n] 并累加到z[i...i+n]中for (j=0; j<n; j++) {carry += y->data[i]*x->data[j] + z->data[i+j];z->data[i+j] = carry%BASE;carry /= BASE;}// 將剩余的進(jìn)位,繼續(xù)在z[i+n...n+m]中累加,從而完成y[i]乘以x[0...n]其積累加到z[i...m+n]中for (; j+i<n+m; j++) {carry += z->data[i+j];z->data[i+j] = carry % BASE;carry /= BASE;}} }bignumber_s *calc_mul(bignumber_s *a, bignumber_s *b) {int len = a->len + b->len;bignumber_s *result = make_bignumber_temp(len,a->sign==b->sign?0:1); //a->sign==b->sign為情況一,否則為情況二。mul_impl(a,b,result);return result; }// 大數(shù)加一操作 void plusone(bignumber_s *a) {int len = a->len ;int i;int carry = 1;for (i=0; i<len; i++) {carry += a->data[i];a->data[i] = carry%BASE;carry /= BASE;} } // 大數(shù)除法實(shí)現(xiàn) bignumber_s *calc_div(bignumber_s *a, bignumber_s *b) {bignumber_s *zero = make_bignumber_temp(1,0);if (cmp(b,zero)==0) {// 除數(shù)為0 報(bào)錯(cuò)fprintf(stderr,"Integer division by zero\n");exit(-1);}else if (cmp(a,zero)==0) { // 被除數(shù)為0 ,結(jié)果為0return zero;}int len = a->len;bignumber_s *result = make_bignumber_temp(len,a->sign==b->sign?0:1);a->sign = 0;b->sign = 0;bignumber_s *temp = make_bignumber_temp(len, 0);bignumber_s *aa = a;while(1) {if (cmp(aa, b)>=0) {sub_impl(aa, b, temp);plusone(result);aa = temp;} else {free(temp);return result;}} }int main(int argc, char *argv[]) {bignumber_s *a = make_bignumber_fromstr(argv[1]);bignumber_s *b = make_bignumber_fromstr(argv[3]);if (argc!=4) usage(argv[0]);if (0 == strcmp(argv[2],"+"))print_bignumber(calc_add(a,b));else if (0 == strcmp(argv[2],"-"))print_bignumber(calc_sub(a,b));else if (0 == strcmp(argv[2],"x"))print_bignumber(calc_mul(a,b));else if (0 == strcmp(argv[2],"/"))print_bignumber(calc_div(a,b));else usage(argv[0]);return 0; }2.6.3 演示
編譯命令:
$ gcc -o calculatorv4 calculatorv4.c結(jié)果演示:
大數(shù)計(jì)算器在解決除法問(wèn)題的時(shí)候僅實(shí)現(xiàn)了商的求解,并未對(duì)余數(shù)進(jìn)行過(guò)多的處理,其實(shí)這是不完善的。大家可以在此基礎(chǔ)上,思考思考如何改進(jìn)能夠讓計(jì)算器更加完善。
三、實(shí)驗(yàn)總結(jié)
本實(shí)驗(yàn)通過(guò)完成一個(gè)大數(shù)計(jì)算器的玩具程序,一方面有助于理解計(jì)算機(jī)數(shù)學(xué)運(yùn)算的實(shí)現(xiàn)機(jī)理,另一方面有助于提升c語(yǔ)言的編程能力。 當(dāng)然我們的大數(shù)計(jì)算器,在除法方面的性能還是不太令人滿意的,希望有興趣的讀者朋友,后續(xù)能夠?qū)τ?jì)算器實(shí)現(xiàn)進(jìn)行改進(jìn)。
四、參考鏈接
- C語(yǔ)言接口與實(shí)現(xiàn)
總結(jié)
以上是生活随笔為你收集整理的C语言实现大数计算器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: vb.net 窗体接收键盘事件_(十五)
- 下一篇: DIY一个VR小钢炮