You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言超长整数相乘代码结果错误,求问题排查

超长整数乘法代码问题排查与修复

问题背景

用C语言实现两个长度不超过200位的超长整数乘法,实际输出结果与预期不符,测试用例如下:

测试用例

  • 输入:
    first_num: 2312730179961343894238242938502761288775
    second_num: 8783549656928600320634308588114585640082
  • 预期输出:20313980378767882242186765287491308230145683219100946334095285964698734616679550
  • 实际输出:110313971037876788224218676528749130822101456832190100946334095285964698734616679550

原代码

#include <stdio.h>
#include <string.h>
#include <math.h>

#define MAX_LEN 200

int checkValidInputNum(char*);

int main() {
    
    char first_num[MAX_LEN];
    char second_num[MAX_LEN];
    printf("Please Enter your first number:\n");
    scanf("%s", first_num);
    
    checkValidInputNum(first_num);
    
    
    printf("Please Enter your second number:\n");
    scanf("%s", second_num);
    checkValidInputNum(second_num);
    
    int output_num_len = strlen(first_num) +strlen(second_num);

    int shifting, inputDataRemainder, inputDataQuotient;

    int output_num[output_num_len];
    for (int i = 0; i < output_num_len; i++)
    {
        output_num[i]=0; //Fill output string of output_num_len with zeroes
        //printf("%i", output[i]);
    }
    
    

    for(int i = 0 ; i <strlen(first_num) ; i++)
     {
        for (int j= 0 ; j < strlen(second_num); j++)
         {
            shifting = (strlen(first_num) -1 - i) +(strlen(second_num) -1 - j);
            inputDataRemainder = ((first_num[i]-48) * (second_num[j]-48)) % 10;
            inputDataQuotient = floor((first_num[i]-48) * (second_num[j]-48)/10);

            if (output_num[0+shifting] + inputDataRemainder > 9)
            {
                output_num[1+shifting] += floor((inputDataRemainder + output_num[0+shifting]) / 10);
                output_num[0+shifting] = (output_num[0+shifting] + inputDataRemainder)%10;
                //printf("Check1");
            }
            else
            {
                output_num[0+shifting] += inputDataRemainder;
                //printf("Check2");
            }
            
            if (output_num[1+shifting] + inputDataQuotient > 9)
            {
                output_num[2+shifting] += floor((inputDataQuotient + output_num[1+shifting]) / 10);
                output_num[1+shifting] = (output_num[1+shifting] + inputDataQuotient)%10;
                //printf("Check3");
            }
            else
            {
                output_num[1+shifting] += inputDataQuotient;
                //printf("Check4");
            }
         }
     }

    if (output_num[output_num_len-1] != 0) printf("%i", output_num[output_num_len - 1]);
    
    printf("The answer is:");
    for (int i = output_num_len - 2; i > -1  ; i--)
    {
        printf("%i", output_num[i]);
        
    }
    printf("\n");
}

int checkValidInputNum(char* text)
{
       for(int i = 0 ; i <strlen(text) ; i++)
       {
           if (text[i] < 48 || text[i] > 57)
           {
               printf("Please Enter your input again:\n");
               scanf("%s", text);
               return checkValidInputNum(text);
           }
       }
       return 0;
}

问题分析

  1. 进位处理不彻底:原代码将乘积拆分为余数和商后,分别对两个位置做局部进位处理,无法应对连续进位场景(比如某一位相加后产生的进位导致下一位也超过10),会导致数值叠加错误。
  2. 乘积拆分处理逻辑冗余且易出错:刻意拆分余数和商分别加到数组的两个位置,不如直接将完整乘积加到对应位置后统一处理进位,逻辑更清晰且不易出错。
  3. 输出逻辑不严谨:仅单独处理最高位的前导零,未考虑中间可能存在的前导零情况,且输出顺序的处理容易导致数值顺序错误。

修复方案

  1. 调整乘积累加逻辑:不再拆分余数和商,直接将两个数字的乘积加到对应的数组位置(shifting对应的索引)。
  2. 统一处理所有进位:遍历输出数组,从最低位到最高位,依次计算每一位的进位,将进位传递到下一位,当前位保留个位数值。
  3. 修正输出逻辑:找到第一个非零的最高位索引,从该索引开始依次输出到最低位,确保无多余前导零;若结果全为零,则输出0。

修复后的代码

#include <stdio.h>
#include <string.h>

#define MAX_LEN 200

int checkValidInputNum(char*);

int main() {
    char first_num[MAX_LEN];
    char second_num[MAX_LEN];
    printf("Please Enter your first number:\n");
    scanf("%s", first_num);
    checkValidInputNum(first_num);

    printf("Please Enter your second number:\n");
    scanf("%s", second_num);
    checkValidInputNum(second_num);

    int len1 = strlen(first_num);
    int len2 = strlen(second_num);
    int output_num_len = len1 + len2;
    int output_num[output_num_len];

    // 初始化输出数组为0
    for (int i = 0; i < output_num_len; i++) {
        output_num[i] = 0;
    }

    // 累加所有乘积到对应位置
    for (int i = 0; i < len1; i++) {
        int digit1 = first_num[i] - '0';
        for (int j = 0; j < len2; j++) {
            int digit2 = second_num[j] - '0';
            int shifting = (len1 - 1 - i) + (len2 - 1 - j);
            output_num[shifting] += digit1 * digit2;
        }
    }

    // 统一处理进位
    for (int i = 0; i < output_num_len - 1; i++) {
        output_num[i + 1] += output_num[i] / 10;
        output_num[i] = output_num[i] % 10;
    }

    // 找到第一个非零的最高位
    int start_idx = output_num_len - 1;
    while (start_idx > 0 && output_num[start_idx] == 0) {
        start_idx--;
    }

    // 输出结果
    printf("The answer is:");
    for (int i = start_idx; i >= 0; i--) {
        printf("%d", output_num[i]);
    }
    printf("\n");

    return 0;
}

int checkValidInputNum(char* text) {
    int len = strlen(text);
    for (int i = 0; i < len; i++) {
        if (text[i] < '0' || text[i] > '9') {
            printf("Please Enter your input again:\n");
            scanf("%s", text);
            return checkValidInputNum(text);
        }
    }
    return 0;
}

内容的提问来源于stack exchange,提问作者Revanth Tv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 22:37:07