Python转C实现Luhn校验和算法遇问题:输出不符求排查
Luhn算法C实现错误排查
我用C实现Luhn校验和算法时,输出结果始终错误(得到11而非预期的29),但用Python重写后2分钟就运行正常。搞不懂两种实现的差异,麻烦帮忙审查C代码定位问题,以下是两种实现的对比代码:
Python 实现
x = 4003600000000014 def checkSum(n): sm = 0 swm = 0 j = 10 k = 100 l = 100 m = 1000 for i in range(0, len(str(n)) // 2): sm += (((n % k) - (n % j)) // j)*2 j *= 100 k *= 100 swm += n % 10 for i in range(0, len(str(n)) // 2): swm += ((n % m) - (n % l)) // l l *= 100 m *= 100 return sm+swm print(checkSum(x))
C 实现(存在错误)
#include <stdio.h> #include <stdlib.h> #include <string.h> int checkSum(long n); int longLength(long n); int main(void) { long long number = 4003600000000014; printf("%d\n", checkSum(number)); return 0; } int longLength(long n) { int length = 0; while (n > 0) { n = n/10; length++; } return length; } int checkSum(long n) { int sm = 0; int swm = 0; int j = 10; int k = 100; int l = 100; int m = 1000; for(int i=0;i<longLength(n)/2;i++) { sm += (((n % k)-(n % j))/j)*2; j *= 100; k *= 100; } swm+= n % 10; for(int i=0 ;i<longLength(n)/2;i++) { swm +=(((n % m)-(n % l))/l); l *= 100; m *= 100; } return sm + swm; }
错误原因分析
数值溢出(核心问题):
- 传入的数字
4003600000000014是long long类型(16位数字,值约4×10¹⁵),但checkSum和longLength函数的参数是long类型。通常32位系统中long最大只能存储约2×10⁹,远小于目标数值,导致传入函数时数值被截断,后续计算全部错误。 - 循环中使用的
j、k、l、m是int类型,循环几次后数值会超过int的最大值(约2×10⁹),再次引发溢出,破坏计算逻辑。
- 传入的数字
冗余计算(次要问题):
循环中每次调用longLength(n)重复计算长度,虽然不影响结果正确性,但会降低效率,建议提前计算一次并存入变量。
修正后的C代码
#include <stdio.h> #include <stdlib.h> #include <string.h> int checkSum(long long n); int longLength(long long n); int main(void) { long long number = 4003600000000014; printf("%d\n", checkSum(number)); return 0; } int longLength(long long n) { int length = 0; while (n > 0) { n = n/10; length++; } return length; } int checkSum(long long n) { int sm = 0; int swm = 0; long long j = 10; long long k = 100; long long l = 100; long long m = 1000; int len = longLength(n); for(int i=0;i<len/2;i++) { sm += (((n % k)-(n % j))/j)*2; j *= 100; k *= 100; } swm+= n % 10; for(int i=0 ;i<len/2;i++) { swm +=(((n % m)-(n % l))/l); l *= 100; m *= 100; } return sm + swm; }
内容的提问来源于stack exchange,提问作者Ahmed Seddik Bouchiba
相关产品推荐
相关产品推荐

