大数运算之大数相减
来源:互联网 发布:软件产品设计流程 编辑:程序博客网 时间:2024/06/04 19:18
大数减法运算
第一次在CSDN写博客,督促自己不断学习、巩固和进步,希望能和大家一起成长~
在编程实现整数运算时,作为程序猿/媛,我们知道计算机中的int、long或者long long的所占的内存空间是有限的,当整数超过一定大小,这些类型就无法表示整数的值,否则数据会被“截断”,无法得到正确的结果。
那么,该如何实现大数运算呢?刚开始我也是如此的疑惑,但稍加思索,你很快可以想到最简单的方法——使用int数组(或者char数组,既满足要求,又可节省空间)来进行运算。假设有两个大数,char *s1 = "4543636436274354646", char *s2 = "456360989", 我们可以取出每一位的值,放到int数组。
值得注意的是,char *中低地址存放的是高位的数字字符,而运算中我们需要将低位对齐,所以首先将字符串的字符逆序存入数组中, 个位数是数组第一个元素:
int idx, len1, len2, *array1, *array2;
len1 = strlen(s1);
array1 = (int *)calloc(len1, sizeof(int));
for (idx = 0; idx < len1; idx++){
array1[idx] = s1[len1 - 1 - idx] - '0';
}
照此将s2的数字存到array2中,简单起见,这里假设array1表示的数字大于等于array2表示的数值。接着就是按照减法的定义,被减数当前位小于减数,则向高位借1,自身加10,逻辑如下:
for (idx = 0; idx < len2; idx++) {
if (array1[idx] < array2[idx]) {
array1[idx+1]--;array1[idx] += 10;
}
array1[idx] -= array2[idx];
}
运算结束后,需要将结果以字符串形式返回。这里有一点很容易被忽略,数组中最高位的0需要清除,不显示到结果的字符串中。
方法同样很简单,从array1最大的元素开始遍历,直到第一个不为0的数字,该位置及之前的数组元素即为运算结果。
最后,还需注意将数组的元素值 + ‘0’,并逆序写到字符串中,注意将字符串存储结果后的一位赋值'\0',表示结束,得到正确的结果。完整代码如下:
/**
* the value of s1 is larger than s2
*/
char *sub(const char *s1, const char *s2)
{
* the value of s1 is larger than s2
*/
char *sub(const char *s1, const char *s2)
{
char *result = NULL;int *array1, *array2;int len1, len2, idx, retLen;if (NULL == s1 || NULL == s2) {
printf("input error, cannot be null\n");return NULL;
}
len1 = strlen(s1);len2 = strlen(s2);if (0 == len1 || 0 == len2) {
printf("input string length cannot be 0\n");return NULL;
}
array1 = (int *)calloc(len1, sizeof(int));if (NULL == array1) {
printf("calloc error:%s\n", strerror(errno));return NULL;
}array2 = (int *)calloc(len2, sizeof(int));if (NULL == array2) {
printf("calloc error:%s\n", strerror(errno));free(array1);return NULL;
}result = (char *)calloc(len1+1, sizeof(char));if (NULL == result) {
printf("calloc error:%s\n", strerror(errno));free(array1);free(array2);return NULL;
}for (idx = 0; idx < len1; idx++) {
array1[idx] = s1[len1-idx-1] - '0';
}for (idx = 0; idx < len2; idx++) {
array2[idx] = s2[len2-idx-1] - '0';
}for (idx = 0; idx < len2; idx++) {
if (array1[idx] < array2[idx]) {
array1[idx+1]--;array1[idx] += 10;
}array1[idx] -= array2[idx];
}retLen = len1 - 1;for (idx = len1-1; idx >= 0; idx--) {
if (retLen == idx && array1[idx] == 0) {
retLen--;
} else {
break;
}
}retLen = (retLen < 0) ? 0 : retLen;for (idx = retLen; idx >= 0; idx--) {
result[retLen-idx] = array1[idx] + '0';
}result[retLen+1] = '\0';free(array1);free(array2);return result;
}
阅读全文
3 0
- 大数运算之大数相减
- 大数运算之大数乘法
- 大数运算之乘法
- 最大公约数之大数运算
- 大数运算之阶乘
- 大数运算之加法
- 大数运算之加减乘除
- 大数运算(二)——大数相减
- 大数运算之加减乘法
- 大数运算之乘法函数
- 大数运算之字符串模拟
- 大数运算之高精度加减法
- 大数处理---大数相减
- 大数运算
- 大数运算
- 大数运算
- 大数运算
- 大数运算
- USACO-Section1.3 Prime Cryptarithm
- java的一些简单注释要求
- 《移动App测试实战》读书笔记
- 大数据:一周电影榜20170602
- Python爬虫-爬取慕课网课程
- 大数运算之大数相减
- 欢迎使用CSDN-markdown编辑器
- 二叉树(binary tree)
- hdu5820 询问简单路径 主席树
- 计时
- MariaDB SQL语句基础
- vue.js支持js原生写法
- NMAP的常用命令
- 《捉虫记——大容量Web应用性能测试与LoadRunner实战》读书笔记