大数加法和大数乘法
2013-11-08 21:41
225 查看
面试或者笔试的时候经常会遇到这样的题目,比如写一个计算两数之和的程序。如果对于加数与和有限制,比如说,保证不会溢出,那么还好,如果没有限制,很可能就会调入陷阱,因此靠考虑溢出的情况,这个时候就需要考虑用字符串模拟加法运算了,乘法也是一样。
用字符串模拟加法运算其实很简单,两个数相加,和的长度最长为较长字符串+1,然后对应位分别相加,注意加上进位,后期可以补上代码。这里主要说下大数乘法。
大数乘法需要模拟乘法的运算,其实写一个竖式计算就可以看出来了,比如56*23,这里就不写竖式了,直接写结果吧,我们注意到
3*6 = 8(进位1)
3*5 + 2*6 + 1 = 8(进位2)
2*5 + 2 = 2(进位1)
于是结果为1288,上面的计算过程,可以看作是将23倒过来,变为32,然后呢,3和6对齐,相乘;然后移位,56与32对齐,对应位相乘,和相加,再加上进位;然后再移位,2和5对齐,相乘,加上进位,得到最终结果。这个过程类似什么?对了,类似卷积,是的,信号处理里面的卷积计算,倒序,相乘相加,明白了这点,就不难写出代码了,其实就是普通卷积的代码:
这里只是最基本的卷积方法,如果位数较多,可以采用比如DFT快速傅里叶变换的方法等,博主水平有限,尚未进一步优化。
用字符串模拟加法运算其实很简单,两个数相加,和的长度最长为较长字符串+1,然后对应位分别相加,注意加上进位,后期可以补上代码。这里主要说下大数乘法。
大数乘法需要模拟乘法的运算,其实写一个竖式计算就可以看出来了,比如56*23,这里就不写竖式了,直接写结果吧,我们注意到
3*6 = 8(进位1)
3*5 + 2*6 + 1 = 8(进位2)
2*5 + 2 = 2(进位1)
于是结果为1288,上面的计算过程,可以看作是将23倒过来,变为32,然后呢,3和6对齐,相乘;然后移位,56与32对齐,对应位相乘,和相加,再加上进位;然后再移位,2和5对齐,相乘,加上进位,得到最终结果。这个过程类似什么?对了,类似卷积,是的,信号处理里面的卷积计算,倒序,相乘相加,明白了这点,就不难写出代码了,其实就是普通卷积的代码:
char *EX_BigMultiply(char *a, char *b) { if (CheckInput(a, b)) { 检查a、b的状态,并做相关处理,比如是否是数字串,正负等等,实际情况是博主也没实现这个函数- - return NULL; } int len_a = strlen(a); int len_b = strlen(b); int cnt = len_a + len_b - 1; //记录积的长度 char *res = (char *)malloc(sizeof(char) * (cnt + 1)); //分配内存,考虑到有字符串结尾,多分配一个字节。 res[cnt--] = '\0'; //字符结尾 int c = 0; while (cnt >= 0) { int sum = 0; for (int i = len_a - 1; i >= 0; i--) { if (cnt - i < 0 || cnt - i >= len_b) { //保证b数组索引的有效性 continue; } sum += (a[i] - '0') * (b[cnt - i] - '0'); //记录该次的和 } sum += c; //加上上次进位 c = sum / 10; //计算本次进位 res[cnt--] = sum % 10 + '0'; //计算本次应该保存的数字 } return res; }
这里只是最基本的卷积方法,如果位数较多,可以采用比如DFT快速傅里叶变换的方法等,博主水平有限,尚未进一步优化。
相关文章推荐
- 大数加法和乘法
- 大数运算(大数加法and大数乘法)
- 大数加法与乘法
- 大数加法 减法 乘法 除法 高精度四则运算
- 大数运算——加法,减法,乘法 .
- 99的99次方----大数乘法和大数加法
- 基础算法,大数加法和乘法的实现
- 大数加法和乘法
- 剑指offer编程题Java实现——面试题12相关题大数的加法、减法、乘法问题的实现
- 大数加法.减法.乘法.除法
- 蓝桥杯——算法提高 大数加法&大数乘法&冒泡排序
- 大数运算之加法乘法---JAVA实现
- [acm 1001] c++ 大数加法 乘法 幂
- 大数加法、大数乘法、大数减法。Swift。
- 大数加法、减法、乘法
- 大数加法与乘法
- 大数加法、减法和乘法
- 大数与小数模板(乘法,加法)
- Java大数模板——加法、减法、乘法、除法、开方、求余
- 大数加法乘法