大整数加法实现求助:数组方案存bug,求简便实现方法
大整数加法的Bug修复与简便实现方案
问题描述
尝试用数组拆分数字的方式实现大整数加法,但代码存在Bug:计算999+999时输出998;处理不同位数(如23位+25位)大整数时逻辑过于复杂。求更简便的实现方式。
原代码如下:
#include <stdio.h> int main(void) { int length_A, length_B, times; long long int A[101] = {0}; long long int B[101] = {0}; long long int total[101] = {0}; scanf("%d", &length_A); for (int i = 0; i < length_A; i++) { scanf("%1lld", &A[i]); } scanf("%d", &length_B); for (int j = 0; j < length_B; j++) { scanf("%1lld", &B[j]); } if (length_A > length_B) { times = length_A - length_B; for (int l = 0; l < times; l++) { total[l] = A[l]; } for (int k = 0; k < length_B; k++) { total[k+times] = A[k+times] + B[k]; if(total[k+times] > 9) { if (total[k+times-1] == 9) { total[k+times-2]++; total[k+times-1] = 0; total[k+times] -= 10; } else if (total[k+times-1] < 9) { total[k+times-1]++; total[k] -= 10; } } } for (int z = 0; z < length_B; z++) { printf("%lld", total[z]); } } else if (length_B > length_A) { times = length_B - length_A; for (int k = 0; k < length_B; k++) { for (int l = 0; l < times; l++) { total[l] = B[l]; } total[k+times] = A[k] + B[k+times]; if(total[k] > 9) { if (total[k-times] == 9) { total[k-times-1]++; total[k-times] = 0; total[k] -= 10; } else { total[k-1]++; total[k] -= 10; } } } for (int z = 0; z < length_B; z++) { printf("%lld", total[z]); } } else { for (int k = 0; k < length_B; k++) { total[k] = A[k] + B[k]; if(total[k] > 9) { if (total[k-1] == 9) { total[k-2]++; total[k-1] = 0; total[k] -= 10; } else { total[k-1]++; total[k] -= 10; } } } for (int z = 0; z < length_B; z++) { printf("%lld", total[z]); } } }
原代码问题分析
- 进位逻辑错误:仅处理了单次相邻进位,遇到连续9的情况(如999+999),无法正确传递连续进位,导致结果错误。
- 位数处理冗余:分三种情况编写重复逻辑,代码冗余且易出错。
- 存储方向不合理:高位存在数组小下标位置,加法需从低位开始计算,增加了进位处理复杂度。
简便实现方案
核心思路
- 用字符串接收大整数,无需提前输入长度,适配任意位数。
- 反转字符串,让低位对应数组小下标,从左到右遍历即从低位到高位相加,进位处理更直观。
- 统一计算每一位的和与进位,最后处理剩余进位。
- 反转结果得到正确顺序。
示例代码
#include <stdio.h> #include <string.h> // 反转字符串函数 void reverse(char *str) { int len = strlen(str); for (int i = 0; i < len / 2; i++) { char temp = str[i]; str[i] = str[len - i - 1]; str[len - i - 1] = temp; } } int main() { char num1[1000], num2[1000], result[1001] = {0}; int len1, len2, max_len, carry = 0; // 输入两个大整数 scanf("%s %s", num1, num2); len1 = strlen(num1); len2 = strlen(num2); // 反转字符串,低位在前 reverse(num1); reverse(num2); // 取较长的长度作为遍历上限 max_len = len1 > len2 ? len1 : len2; // 逐位相加 for (int i = 0; i < max_len; i++) { // 取出当前位的数字,超出长度的位视为0 int digit1 = i < len1 ? num1[i] - '0' : 0; int digit2 = i < len2 ? num2[i] - '0' : 0; // 计算当前位总和+进位 int sum = digit1 + digit2 + carry; // 当前位结果 result[i] = (sum % 10) + '0'; // 更新进位 carry = sum / 10; } // 如果最后还有进位,追加到结果 if (carry != 0) { result[max_len] = carry + '0'; max_len++; } // 反转结果得到正确顺序 reverse(result); // 输出结果 printf("%s\n", result); return 0; }
代码优势
- 无需区分位数长短,逻辑统一。
- 进位处理彻底,支持连续进位场景。
- 字符串输入更符合用户习惯,无需提前输入长度。
内容的提问来源于stack exchange,提问作者Richard Bryan
相关产品推荐
相关产品推荐

