大整数加减乘除 c实现
2016-03-28 23:36
543 查看
最近准备一下笔试,发现自己的算法方面的编程有点弱鸡,菜的抠脚。前几天做了腾讯的一个笔试模拟,需要实现的是大整数的乘法,于是乎就想着把加减乘除都实现了。网上也参考过,主要给思路和坑。
最主要的
既然是大整数,那么一定是数组存储,不可能是long等。
使用字符char可以完成计算,但要减去’0’
之后要加回来
加法
分配一个比两个加数大1位的字符串数组,作为返回
使用加数中位数少进行加,注意不要越界,另一个加数直接加到结果上面
最后对结果进行清除首位可能的0
减法
分配被减数位数的字符串数组作为返回
减数位数循环,最主要的是注意借位!
被减数剩下的直接赋予结果
注意100-100=0 而不是000
乘法
对应位数相乘,注意进位,相对简单一些
首位可能清零
除法
最麻烦的除法来了,除法中存在除数,被除数,余数,商。除数可能为0
余数是5而不是05之类的
商也是5而不是005之类
除法的思想主要是我们小时候画的除法“厂”一位一位除,其中注意循环条件在跳至最后一位结束,然后余数继续加被除数的剩余位数,继续做除法。
废话不多说了,这里应该还有一种保留多少位小数的要求,这里你可以得到商和余数后继续加入循环,如果保留6位小数,那么你在余数末尾加7个0,保证最后四舍五入。这个没有实现,有兴趣的你们可以试试。在写代码时我也很晕,所以用了goto条件,希望你能指点哈~~
代码
最主要的
既然是大整数,那么一定是数组存储,不可能是long等。
使用字符char可以完成计算,但要减去’0’
之后要加回来
加法
分配一个比两个加数大1位的字符串数组,作为返回
使用加数中位数少进行加,注意不要越界,另一个加数直接加到结果上面
最后对结果进行清除首位可能的0
减法
分配被减数位数的字符串数组作为返回
减数位数循环,最主要的是注意借位!
被减数剩下的直接赋予结果
注意100-100=0 而不是000
乘法
对应位数相乘,注意进位,相对简单一些
首位可能清零
除法
最麻烦的除法来了,除法中存在除数,被除数,余数,商。除数可能为0
余数是5而不是05之类的
商也是5而不是005之类
除法的思想主要是我们小时候画的除法“厂”一位一位除,其中注意循环条件在跳至最后一位结束,然后余数继续加被除数的剩余位数,继续做除法。
while(被除数指针越界) { "余数"+"被除数对应位" > "除数" 时 除法,得到商和余数 商存储 余数继续参与循环 }
废话不多说了,这里应该还有一种保留多少位小数的要求,这里你可以得到商和余数后继续加入循环,如果保留6位小数,那么你在余数末尾加7个0,保证最后四舍五入。这个没有实现,有兴趣的你们可以试试。在写代码时我也很晕,所以用了goto条件,希望你能指点哈~~
代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXINT 1000 char *fun_cal(char *a,char *b) { int size_a = strlen(a); int size_b = strlen(b); int size_res = size_a + size_b; char *result = malloc((size_res+1)*sizeof(char)); memset(result,0,(size_res + 1)); int i=size_a-1; int j=size_b-1; for(i;i>=0;i--) { for(j=size_b-1;j>=0;j--) { int k = i+j+1; result[k] += (a[i] - '0') * (b[j] - '0'); if (result[k] >= 10) { result[k-1] += result[k]/10; result[k] %= 10; } } } int flag = result[0] == 0 ?1:0; i=0; for(i;i<size_res-flag;i++) result[i] = result[i+flag] + '0'; result[size_res-flag] = '\0'; return result; } int compare(char *a,char *b) { int size_a = strlen(a); int size_b = strlen(b); if (size_a > size_b) { return 1; } else if (size_a < size_b) { return -1; } else { int p = 0; while(p < size_a) { if (a[p] > b[p]) { return 1; } else if (a[p] < b[p]) { return -1; } else p++; } return 0; } } void fun_clean_zero(char *str) { int flag = 0,i; while(str[0] == '0' && strlen(str) > 1) { int size_res = strlen(str); flag = 1; for(i=0;i<size_res-flag;i++) str[i] = str[i+flag] ; str[size_res-flag] = '\0'; } } char *fun_dec(char *a,char *b) { int size_b = strlen(b); int size_a = strlen(a); int size_res = size_a > size_b ? size_a : size_b; char *result = malloc((size_res+1)*sizeof(char)); memset(result,0,(size_res)); int i = 1; for(i;i<=size_a;i++) { if (b[size_b-i]<a[size_a-i]) { result[size_res-i] = (b[size_b-i] - '0' +10)-(a[size_a-i] - '0'); int j=1; while((i+j) <= size_b) { if (b[size_b-i-j] > '0') { b[size_b-i-j] --; for(--j;j>0;j--) { b[size_b-i-j] += 9; } break; } j++; } } else result[size_res-i] = (b[size_b-i] - '0')-(a[size_a-i] - '0'); } for (i = size_a+1; i <= size_b; ++i) { result[size_res-i] = (b[size_b-i] - '0'); } // do // { // int flag = 0; // printf("once\n"); // if (result[0] == 0 ) // { // flag = 1; // } // int j; // printf("flag %d\n",flag); // for(j=0;j<size_res;j++) // { // result[j] = result[j+flag]; // } // result[size_res-flag] = '\0'; // printf("len is %d\n",strlen(result) ); // }while(result[0] == 0 && strlen(result)>1); // i=0; // for(i;i<strlen(result);i++) // result[i] = result[i] + '0'; int flag = result[0] == 0 ?1:0; i=0; for(i;i<size_res-flag;i++) result[i] = result[i+flag] + '0'; result[size_res-flag] = '\0'; // while(result[0] == '0' && strlen(result) > 1) // { // printf("once \n"); // flag = 1; // for(i=0;i<size_res-flag;i++) // result[i] = result[i+flag] ; // result[size_res-flag] = '\0'; // } // printf("len is %d\n",strlen(result) ); fun_clean_zero(result); return result; } int fun_div(char *a,char *b,char *c,char *d) { if (compare(b,"0") == 0) { printf("b is zero\n"); return -1; } int size_a = strlen(a); int i=0; char *tmp = malloc(1000*sizeof(char)); memset(tmp,0,1000); while(i <= size_a) { while(compare(tmp,b) < 0) { memcpy(tmp+strlen(tmp),a+i,1); if (c[i] == 0) { c[i]='0'; } i++; if (i > size_a) { goto end; } } int j=0; char jj[5]; sprintf(jj,"%d", j); while(compare(tmp,fun_cal(jj,b))>0 ) { j++; sprintf(jj,"%d", j); } if (compare(tmp,fun_cal(jj,b)) == 0) { sprintf(jj,"%d", j); } else { sprintf(jj,"%d", j-1); } c[i] = jj[0]; tmp = fun_dec(fun_cal(jj,b),tmp); if (compare(tmp,"0") == 0) { memset(tmp,0,1000); } } end: fun_clean_zero(c); if (strlen(tmp) == 0) { memcpy(d,"0",1); } else memcpy(d,tmp,strlen(tmp)); return 0; } char * fun_sum(char *a, char *b) { int size_b = strlen(b); int size_a = strlen(a); int size_res = size_a > size_b ? size_a : size_b; size_res++; char *result = malloc((size_res+2)*sizeof(char)); memset(result,0,(size_res)); int i = 1; for(i;i<=size_a;i++) { result[size_res-i] = (a[size_a-i] - '0') + (b[size_b-i] - '0') + result[size_res-i]; if (result[size_res-i] >= 10) { result[size_res-i] %=10; result[size_res-i-1] +=1; } } for (i = size_a+1; i <= size_b; ++i) { result[size_res-i] += (b[size_b-i] - '0'); if (result[size_res-i] >= 10) { result[size_res-i] %=10; result[size_res-i-1] +=1; } } int flag = result[0] == 0?1:0; int j; for(j=0;j<size_res;j++) { result[j] = result[j+flag] + '0'; } result[size_res-flag] = '\0'; return result; } int main(int argc, char const *argv[]) { char *a = malloc(1000*sizeof(char)); char *b = malloc(1000*sizeof(char)); char *c ,*d; scanf("%s%s",a,b); int size_b = strlen(b); int size_a = strlen(a); // int size_res = size_a > size_b ? size_a : size_b; // char *result = malloc((size_res+1)*sizeof(char)); // memset(result,0,(size_res)); c = malloc((size_a+1)*sizeof(char)); memset(c,0,size_a); d = malloc((size_a+1)*sizeof(char)); memset(d,0,size_a); /* dec */ // result = fun_dec(a,b); // printf("result is %s\n",result ); /* div */ int ret = fun_div(a,b,c,d); printf("d id %s c is %s\n",d,c ); /* sum */ // result = fun_sum(a,b); // printf("result is %s\n",result ); // return 0; /* cal */ // result = fun_cal(a,b); // printf("result is %s\n",result ); return 0; }
相关文章推荐
- Linux C函数参考手册(PDF版)
- C# partial关键字说明
- Lua教程(十七):C API简介
- 简单谈谈lua和c的交互
- C#中的委托数据类型简介
- C#编写的艺术字类实例代码
- C#实现打造气泡屏幕保护效果
- 举例讲解C#编程中委托的实例化使用
- 使用C#代码获取存储过程返回值
- C/C++数据对齐详细解析
- 利用C语言来求最大连续子序列乘积的方法
- 字符串的组合算法问题的C语言实现攻略
- C 语言基础教程(我的C之旅开始了)[三]
- 学习C和C++的9点经验总结
- C++中的extern “C”用法详解
- C 语言基础教程(我的C之旅开始了)[七]
- 最大子矩阵问题实例解析
- C字符串操作函数实现方法小结
- C语言中static的作用及C语言中使用静态函数有何好处