I'm currently working on implementing the Luhn algorithm in C for checksum calculation. However, I encountered an issue with my C code where it consistently produces incorrect output (giving 11 instead of the expected 29). Frustrated by this, I decided to rewrite the algorithm in Python, which surprisingly worked flawlessly within just 2 minutes. I'm now puzzled about what might be causing the discrepancy between the C and Python implementations. Could someone please lend a hand in reviewing my C code and help identify the underlying issue? Below are both implementations for comparison:
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))
#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;
}
A long
number is possibly narrower than a long long
.
Use a wider argument in the declaration and definition to not lose information.
// int longLength(long n);
int longLength(long long n);
// int checkSum(long n);
int checkSum(long long n);
// int longLength(long n)
int longLength(long long n)
...
// int checkSum(long n)
int checkSum(long long n)
...
Save time and enable all compiler warnings to receive something like:
warning: conversion from 'long long int' to 'long int' may change value [-Wconversion]
This will indicate many of the int
variables should be long long
.
// warning: conversion from 'long int' to 'int' may change value [-Wconversion]
sm += (((n % k) - (n % j)) / j) * 2;