1

I'm working on cs50 and I'm getting this error when trying to run. The program asks the user for a credit card number and then reports (via printf) whether it is a valid American Express, MasterCard, or Visa card number, using luhns algorithm and the requirements for each card. source code is below

#include <stdio.h>
#include <cs50.h>

bool validation(long number) {
    int i = 10;
    int j = 1;
    int totalMultiplied = 0;
    int totalNotMultiplied = 0;

    while (number / i != 0){
        totalMultiplied += ((number / i) % 10) * 2;
        i *= 100;
    }
    while (number / j != 0) {
        totalNotMultiplied += (number / j) % 10;
        j *= 100;
    }

    if ((totalMultiplied + totalNotMultiplied) % 10 == 0) {
        return true;
    }else {
        return false;
    }
}

int main(void) {
    long creditCardNo;
    do {
        creditCardNo = get_long("Enter credit card number: ");
    }
    while (creditCardNo < 0);

    int count = 0;
    long startNumbers = creditCardNo;
    long n = creditCardNo;

    do {
        n /= 10;
        count++;
    }
    while (n != 0);

    while (startNumbers >= 100) {
        startNumbers /= 10;
    }

    if (validation(creditCardNo)) {
        if (count == 15 && ( startNumbers == 34 || startNumbers == 35)) {
            printf("AMEX\n");
        }
        else if (count == 16 && ( startNumbers == 51 || startNumbers == 52 || startNumbers == 53 || startNumbers == 54 || startNumbers == 55)) {
            printf("MASTERCARD\n");
        }
        else if ((count == 13 || count == 14) && ( startNumbers / 10 == 4)) {
            printf("VISA\n");
        }
    }else {
        printf("INVALID\n");
    }


}



I expected the program to print what type of card it was if the card was valid or invalid if the card was invalid

9
  • 1
    "Floating point exception" in integer calculation happens when you divide by zero. Since you don't do this explicitly as far as I can tell, I'd suspect that your i or j are overflowing Commented Sep 11, 2024 at 13:25
  • 1
    Credit card "numbers" are not numbers in the arithmetic sense. They are digit strings, and they are best handled that way. Otherwise, you will run into issues with significant leading zeroes, possibly with arithmetic overflow, and maybe with other details as well. Commented Sep 11, 2024 at 13:29
  • 1
    Are you sure long can hold numbers with 15 digits (48+ bits)? Commented Sep 11, 2024 at 13:32
  • It works when i use shorter numbers but doesn't work using the actual credit card numbers incase that brings any clarity. Pertaining the use of long, the walkthrough basically told us to use get_long for the user input. Could you also explain what you mean by i or j are overflowing? Commented Sep 11, 2024 at 13:43
  • 1
    If you use long for number and you divide number / i until the result is 0, you must be prepared that i gets larger than number, which means you need to use long for i as well. And you still risk that i *= 100 overflows. Commented Sep 11, 2024 at 13:59

1 Answer 1

0

In testing out your code utilizing the good comments above regarding the use of "long long" designations for your integer variables, following was the initial refactoring of the code to pass and use "long long" variables in the validation function.

First off, in the main function, the credit card number was refactored to be a "long long" variable.

int main(void)
{
    long long creditCardNo;
    do
    {
        creditCardNo = get_long_long("Enter credit card number: ");
    }

Then, the function was also refactored in the same way.

bool validation(long long number)   /* Refactored to handle large credit card values    */
{
    long i = 10;
    long j = 1;
    int totalMultiplied = 0;
    int totalNotMultiplied = 0;

    while (number / i != 0)
    {
        totalMultiplied += ((number / i) % 10) * 2;
        printf("totalMultiplied: %d\n", totalMultiplied);           /* Using printf as a manual debug tool  */
        i *= 100;
    }
    while (number / j != 0)
    {
        totalNotMultiplied += (number / j) % 10;
        printf("totalNotMultiplied: %d\n", totalNotMultiplied);     /* Using printf as a manual debug tool  */
        j *= 100;
    }

    if ((totalMultiplied + totalNotMultiplied) % 10 == 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}

While that did address the overflow issues, there was still some refinement of the check digit calculation that needed to be performed in the function as testing of the program with a "technically valid" Amex credit card number came back as invalid.

craig@Vera:~/C_Programs/Console/ValidCC/bin/Release$ ./ValidCC 
Enter credit card number: 350000000000006
totalMultiplied: 0
totalMultiplied: 0
totalMultiplied: 0
totalMultiplied: 0
totalMultiplied: 0
totalMultiplied: 0
totalMultiplied: 10
totalNotMultiplied: 6
totalNotMultiplied: 6
totalNotMultiplied: 6
totalNotMultiplied: 6
totalNotMultiplied: 6
totalNotMultiplied: 6
totalNotMultiplied: 6
totalNotMultiplied: 9
INVALID

Further investigation as to how the Luhn check digit algorithm works, there needs to be accommodation when the resulting calculated value exceeds a value of "9" as noted in the following link:

"https://en.wikipedia.org/wiki/Luhn_algorithm"

With that in mind, another refactoring refinement was done to mimic the Luhn check digit algorithm.

bool validation(long long number)       /* Refactored to handle large credit card values    */
{
    long i = 10;
    long j = 1;
    int totalMultiplied = 0;
    int totalNotMultiplied = 0;

    while (number / i != 0)
    {
        if (((number / i % 10) < 5))                            /* Luhn test    */
            totalMultiplied += ((number / i) % 10) * 2;
        else
            totalMultiplied += ((number / i) % 10) * 2 - 9;
        printf("totalMultiplied: %d\n", totalMultiplied);       /* Using printf as a manual debug tool  */
        i *= 100;
    }
    while (number / j != 0)
    {
        totalNotMultiplied += (number / j) % 10;
        printf("totalNotMultiplied: %d\n", totalNotMultiplied); /* Using printf as a manual debug tool  */
        j *= 100;
    }

    if ((totalMultiplied + totalNotMultiplied) % 10 == 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}

Following is the resulting terminal output utilizing the same test credit card number.

craig@Vera:~/C_Programs/Console/ValidCC/bin/Release$ ./ValidCC 
Enter credit card number: 350000000000006
totalMultiplied: 0
totalMultiplied: 0
totalMultiplied: 0
totalMultiplied: 0
totalMultiplied: 0
totalMultiplied: 0
totalMultiplied: 1
totalNotMultiplied: 6
totalNotMultiplied: 6
totalNotMultiplied: 6
totalNotMultiplied: 6
totalNotMultiplied: 6
totalNotMultiplied: 6
totalNotMultiplied: 6
totalNotMultiplied: 9
AMEX

This additional refinement was to be preemptive to avoid further confusion in testing out the program.

The takeaway from all of this is to continue delving into "C" tutorials to get a better understanding of the limitations of the various variable definitions as well as getting properly familiar with the utilization of validation processes such as check digit derivation.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.