0

I even tried to use long int in place of int but then the compiler takes too much time to execute and still doesn't give any output.

I'm using CS50's IDE.

Here's my code that's causing the problem:

int sum_alt = 0;
int sum_rest = 0;
int total = 0;

for(int i = 1; i < count; i=+2)
{
    int temp = number[i] * 2;
    sum_alt = sum_alt + temp;
}

for(int i = 0; i <= count; i=+2)
{
    int temp = number[i];
    sum_rest = sum_rest + temp;
}

total = sum_rest + sum_alt;

How to resolve this problem?

Here's the full code:

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

int main(void)
{
long long Cardnumber;

//Typos correction + User input
do
{
    Cardnumber = get_long_long("Number: ");
}
while(Cardnumber < 0);

int count = 0;
long long counter = Cardnumber;

//To count the number of digits
while(counter != 0)
{
    counter = counter / 10;
    count++;
}

//Declaring an array for cardnumber
printf("%i", count);
int number[count];

if((count != 13) && (count != 15) && (count != 16))
{
    printf("INVALID\n");
}

for(int access = 0; access < count; access++)
{
    number[access] = Cardnumber % 10;
    Cardnumber = Cardnumber / 10;
}

int originalnumber[count];

for(int i = 0; i < count; i++)
{
    originalnumber[i] = number[i];
}

long long int sum_alt = 0;
long long int sum_rest = 0;
long long int total = 0;

for(int i = 1; i < count; i=+2)
{
    int temp = number[i] * 2;
    sum_alt = sum_alt + temp;
}

for(int i = 0; i < count; i=+2)
{
    int temp = number[i];
    sum_rest = sum_rest + temp;
}

total = sum_rest + sum_alt;

if(total % 10 == 0)
{
    if(((count == 13) || (count == 16)))
    {
        if((originalnumber[12] == 4) || originalnumber[15] == 4)
        {
            printf("VISA\n");
        }
        else if(originalnumber[15]== 5)
        {
            if(originalnumber[14] == 1 || originalnumber[14]== 2 || originalnumber[14] == 3 || originalnumber[14] == 4 || originalnumber[14] == 5)
            {
                printf("MASTERCARD\n");
            }
        }

        else
        {
            printf("INVALID\n");
        }
    }
    else if (count == 15)
    {
        if(originalnumber[15] == 3)
        {
            if(originalnumber[15] == 4 || originalnumber[15] == 7)
            {
                printf("AMERICAN EXPRESS\n");
            }
            else
            {
                printf("INVALID\n");
            }
        }
        else
        {
            printf("INVALID\n");
        }
    }
}

else
{
    printf("INVALID\n");
}   

}

PS. I don't get the reason why CS50's IDE is taking so much time for computation.

  • 2
    Your code is not complete. What are you trying to achieve ? Why would a `long int` take longer to compute ? Isn't the computation duration limited by `count` ? Do you also increase the `count` value ? – chmike Dec 24 '19 at 07:29
  • 1
    What is the value of `count` in `for(int i = 1; i < count; i=+2)`?? – David C. Rankin Dec 24 '19 at 07:53
  • 1
    How many elements are there in the array `number[]`? If you have `count` elements, then you are reading beyond the end in the second loop. The `i <= count` is suspect. – HAL9000 Dec 24 '19 at 08:27
  • 1
    @chmike Count is the number of digits of the input Credit Card number by the user. The above code gives the background behind the error message. Count is a finite number too. I don't get the reason why it's taking so long to compute the output? – Hitchiker-V Dec 24 '19 at 08:41
  • 1
    The code you've posted does not have the problem you describe. See [mcve]. – user3386109 Dec 24 '19 at 08:47
  • 1
    If count is the number of digits in a credit card number, the overflow must result from the magnitude of `number[i]` that is close to overflow. Are these numbers that big ? – chmike Dec 24 '19 at 08:48
  • 1
    @chmike My test case that's giving the error described is "4222222222222". – Hitchiker-V Dec 24 '19 at 08:55
  • Are you aware that you store the digits of the card number in reverse order in the `number`array ? You also access `number[15]`when `count` might be 13. These operations should not overflow because you are adding up at most 16 digits multiplied by two. The overflow problem is probably because you read beyond the end of the array. – chmike Dec 24 '19 at 10:40
  • @chmike I'm using the condition ( i=1; i < count; i =+ 2). This stops the increment when i becomes 11 ( when count is 13). This will stop the overflow I guess? – Hitchiker-V Dec 24 '19 at 11:19
  • If you are trying to implement the credit card verification algorithm, what you have implemented is not correct. I regarding the overflow of the array, I was referring to the instructions `if(((count == 13) || (count == 16))) { if((originalnumber[12] == 4) || originalnumber[15] == 4) ` – chmike Dec 24 '19 at 12:29
  • This is also reading beyond the end of the array : `if (count == 15) { if(originalnumber[15] == 3)` – chmike Dec 24 '19 at 12:32
  • The algorithm to verify the validity of credit card numbers is described here: https://www.geeksforgeeks.org/luhn-algorithm/ – chmike Dec 24 '19 at 12:35
  • 1
    It is impossible to have an overflow with the Luhn algorithm. The biggest value you have to deal with in the computation is 16*9. The overflow is with the input value. This is why you shouldn't read the credit card number as an integer. You have to read it as a string and process the characters one by one – chmike Dec 24 '19 at 12:41

2 Answers2

1

This is because 2147483644 + 4 = 2147483648 which is more than 2147483647 (which is signed int32 limit). And 64-bit integer type is long long int, AFAIK.

So it should be:

long long int sum_alt = 0;
long long int sum_rest = 0;
long long int total = 0;

for(int i = 1; i < count; i=+2)
{
    int temp = number[i] * 2;
    sum_alt = sum_alt + temp;
}

for(int i = 0; i <= count; i=+2)
{
    int temp = number[i];
    sum_rest = sum_rest + temp;
}

total = sum_rest + sum_alt;

P.S. Also, the variable "count" is not defined according to this code, so there might be a problem with it.

Clarity
  • 194
  • 3
  • 15
  • 1
    I made a suitable change to the code but the output is still not getting computed. – Hitchiker-V Dec 24 '19 at 08:47
  • 1
    "And 64-bit integer type is long long int, AFAIK." — no it's not. The size is implementation-defined. If you want 64 bits specifically, you need `int64_t`. Check this for more detail: https://stackoverflow.com/a/13604190/3212865 – spectras Dec 24 '19 at 08:56
1

The following code gets a credit card number from the user, check its length and check sum, and determine the issuer.

The program can be tested with credit card numbers obtained from https://ccardgenerator.com/.

The properties of this code is that

  • it doesn't input an integer number that may indeed overflow
  • it processes a sequence of characters
  • the Luhn algorithm is properly implemented (the digits of number[i]*2 must be summed)
  • I refined the tests to recognize the credit card issuer (base on the first 4 digits); the original code had a lot of errors in it
#include <stdio.h>
#include <ctype.h>

int main()
{
    char buf[32];
    printf("enter credit card number: ");
    fgets(buf, sizeof(buf), stdin);

    int len = 0;
    while(isdigit(buf[len]))
        len++;
    if(len < 13 || len > 16) {
        printf("INVALID\n");
        return 1;
    }

    // verify credit card number check sum
    int checkSum = 0;
    for(int i = 0; i < len; i++) {
        int d = buf[len-i-1] - '0'; // get digit from right most to left most 
        if((i&1) == 0)
            checkSum += d;
        else
            checkSum += (d*2)%10 + (d*2)/10;
    }
    if(checkSum%10 != 0) {
        printf("INVALID\n");
        return 1;
    }

    // determine issuer (see https://www.regular-expressions.info/creditcard.html)
    int start = (buf[0]-'0')*1000 + (buf[1]-'0')*100 + (buf[2]-'0')*10 + buf[3]-'0';
    if((len == 13 || len == 16) && start/1000 == 4) {
        printf("VISA\n");
    } else if(len == 16 && ((start >= 5100 && start < 5600) || (start >= 2221 && start <= 2720))) {
        printf("MASTERCARD\n");
    } else if(len == 15 && ((start >= 3400 && start < 3500) || (start >= 3700 && start < 3800))) {
        printf("AMERICAN EXPRESS\n");
    } else if(len == 14 && ((start >= 3000 && start < 3060) || start/100 == 36 || start/100 == 38)) {
        printf("DINERS CLUB\n");
    } else if(len == 16 && (start == 6011 || start/100 == 65)) {
        printf("DISCOVER\n");
    } else if((len == 15 && (start == 2131 || start == 1800)) || (len == 16 && start/100 == 35)) {
        printf("JCB\n");
    } else {
        printf("UNKNOWN\n");
    }

    return 0;
}
chmike
  • 20,922
  • 21
  • 83
  • 106