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

为何这段实现隔位乘2求和的C代码返回异常值?

问题分析与修复

你的代码出现异常结果,核心问题出在浮点数运算的精度误差,还有循环逻辑的小偏差,具体拆解如下:

1. pow函数的精度陷阱

pow(10, i)是浮点数运算,无法保证结果是精确的整数。比如pow(10,2)可能返回99.99999999999999而非精确的100。当你用credit_card / pow(...)时,浮点数转换会导致计算结果偏差,最终取模%10得到错误的数字,这就是你看到初始值完全不合理的原因。

2. 循环逻辑的小偏差

你需要从倒数第二位开始处理,但原代码依赖浮点数索引位的方式本身不可靠,不如直接用整数操作逐位遍历更稳妥。

修复后的代码

#include <stdio.h>

// 计算数字的位数,用整数循环实现,避免浮点数误差
int len(long li) {
    if (li == 0) {
        return 1;
    }
    int count = 0;
    while (li > 0) {
        count++;
        li /= 10;
    }
    return count;
}

int main(void) {
    long credit_card = 378282246310005;
    int sum = 0;
    long temp = credit_card;
    
    // 先跳过最后一位(个位),从倒数第二位开始
    temp /= 10;
    
    // 每隔一位处理一次,直到temp为0
    int step = 0;
    while (temp > 0) {
        if (step % 2 == 0) {
            int digit = temp % 10;
            int doubled = digit * 2;
            // 累加乘积的各位数字:如果是两位数,拆成十位+个位;否则直接加
            sum += (doubled >= 10) ? (doubled / 10 + doubled % 10) : doubled;
            printf("处理的数字:%d,乘2后:%d,当前累加值:%d\n", digit, doubled, sum);
        }
        temp /= 10;
        step++;
    }
    
    printf("最终累加结果:%d\n", sum);
    return 0;
}

关键修复点

  • 替换pow为整数除法/10和取模%10,彻底避免浮点数精度问题;
  • 用temp变量遍历信用卡号的每一位,先跳过个位,直接从倒数第二位开始处理;
  • 简化乘积的各位数字累加逻辑,不用调用len函数,直接判断是否为两位数拆分相加;
  • 重写len函数,用整数循环计数替代log10的浮点数实现,避免潜在误差。

关于你提到的“溢出迹象”

你删除%10 *2后看到的异常,本质还是pow导致的计算偏差,并非真正的整数溢出——你的信用卡号378282246310005是15位,long类型在多数系统是64位,完全能容纳这个数值,不存在溢出问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 13:25:50