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

数组实现高精度除法异常排查:部分用例无输出或结果错误

高精度除法模块异常问题分析

异常现象

  • 输入/ 100000000 999或/ 10000 99无输出
  • / 1000 99输出正确结果10
  • / 30 1得到错误输出29
  • / 1000000000 99计算出错,但/ 2300 200输出正确
  • 疑问:异常是超时导致还是其他原因?

相关代码

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

#define MAX_LEN 1000
int an1[MAX_LEN+10], an2[MAX_LEN+10];
char szLine1[MAX_LEN+10], szLine2[MAX_LEN+10];

void mul(int a[], int an, int b[], int bn, int fa, int fb);
void plus(int an1[], int an2[]);
void div(int an1[], int nlen1, int an2[], int nlen2, int fa, int fb);
void sub(int an1[], int nLen1, int an2[], int nLen2);
int compare_num(int an1[], int nLen1, int an2[], int nLen2);

int main(){
    char op = getchar(); getchar();
    int i = 0, j = 0, nLen1 = 0, nLen2 = 0; 
    memset(an1, 0, sizeof(an1)); memset(an2, 0, sizeof(an2));

    int fa = 1, fb = 1;
    scanf("%s", szLine1); nLen1 = strlen(szLine1);
    scanf("%s", szLine2); nLen2 = strlen(szLine2);
    if(szLine1[0] == '-') fa = -1; if(szLine2[0] == '-') fb = -1;
    if(fa == -1){
        for(i = nLen1-1; i >= 1; i--){
        an1[j++] = szLine1[i] - '0';
        }}else{
        for(i = nLen1-1; i >= 0; i--){
        an1[j++] = szLine1[i] - '0';
        }}
    if(fb == -1){
        for(i = nLen1-1; i >= 1; i--){
        an2[j++] = szLine2[i] - '0';
        }}else{
        for(i = nLen2-1, j = 0; i >= 0; i--){
        an2[j++] = szLine2[i] - '0';
        }
    }
    //以上两个循环将szline中的输入的数组倒置放入an数组中
    switch (op)
    {
    case '+':
        plus(an1, an2);
        break;
    case '-':
        sub(an1, nLen1, an2, nLen2);
        break;
    case '*':
        mul(an1, nLen1, an2, nLen2, fa, fb);
        break;
    case '/':
        div(an1, nLen1, an2, nLen2, fa, fb);
        break;
    default:
        break;
    }

    return 0;
}
int compare_num(int an1[], int nLen1, int an2[], int nLen2){
    int count = 0;
    if(nLen1 > nLen2) return 1;
    else if(nLen1 < nLen2) return -1;
    else if(nLen1 == nLen2){
        for(int i = nLen1; i >= 0; i--){
            if(an1[i] > an2[i]) return 1;
            else if(an1[i] < an2[i]) return -1;
            else if(an1[i] == an2[i]){
                count++;
                continue;
            }
        }
        if(count == nLen1) return 0;
    }
}

void div(int an1[], int nlen1, int an2[], int nlen2, int fa, int fb){
    int count = 0;
    int sign = compare_num(an1, nlen1, an2, nlen2);
    if(sign == 1){

        while(compare_num(an1, nlen1, an2, nlen2) == 1 || compare_num(an1, nlen1, an2, nlen2) == 0){
            for(int i = 0; i <= nlen2; i++){
            if(an2[i] > an1[i]){
                an1[i] = an1[i]+10-an2[i];
                an1[i+1]--;
            }else{
                an1[i] = an1[i] - an2[i];}}
            if(an1[nlen1-1] == 0) nlen1--;
            count++;
            if(nlen1 < nlen2) break;
        }
        if(fa * fb < 0) printf("-");
        printf("%d", count);
    }else{
        printf("0");
    }
}

问题根源分析

  1. 除数初始化错误:处理负数除数时,循环误用了被除数的长度nLen1而非除数长度nLen2,导致an2数组值完全错误,后续比较、减法逻辑全部失效。代码错误片段:

    if(fb == -1){
        for(i = nLen1-1; i >= 1; i--){  // 此处应使用nLen2
        an2[j++] = szLine2[i] - '0';
        }}
    
  2. 减法逻辑缺陷:除法中的逐次减法仅处理当前位借位,未处理高位借位后的连锁反应。例如/30 1时,第一次减完后an1变成29,后续循环无法正确终止,导致计数错误。

  3. 暴力除法导致超时:当前除法采用逐次减去除数的暴力实现,当被除数远大于除数时(如100000000 / 999),循环次数达百万级,程序长时间无响应,表现为“无输出”。

  4. compare_num函数未定义行为:函数存在路径未返回值的情况(如所有位相等但count未达到nLen1时),可能导致比较结果混乱。

修复建议

  • 修正除数初始化的循环变量,将nLen1改为nLen2。
  • 重写减法逻辑,正确处理连续借位:从低位到高位逐位相减,若当前位不够减则向高位借1,高位减1后当前位加10再减。
  • 替换暴力除法为试商法,通过移位快速确定商的每一位,避免大量循环。
  • 简化compare_num函数,去掉冗余的count变量,确保所有分支都有明确返回值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 14:47:11