1234567
1234567

Reputation: 21

Issue with a program in C to check if a number is divisible by 100

I wrote a program in C to check if the entered number is divisible by 100, but I've run into a problem. If I enter a number with 11 digits or more (with the last two digits being zeroes, of course), it says the number is not divisible by 100, even though it is. Help?

#include <stdio.h>
#include <conio.h>
int main()
{
    long int a;
    printf("Enter the number: ");
    scanf("%d" , &a);
    if(a%100==0)
    {printf("This number is divisible by 100");}
    else
    {printf("This number is not divisible by 100");}
    getch();
}

Upvotes: 1

Views: 3173

Answers (2)

zwol
zwol

Reputation: 140659

One of the many reasons why scanf should never be used is that numeric overflow provokes undefined behavior. Your C library seems to produce a garbage value on overflow.

If you write the program using getline and strtol, then you can safely check for overflow and print a proper error message:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

int
main(void)
{
    char *linebuf    = 0;
    size_t linebufsz = 0;
    ssize_t len;
    char *endp;
    long int val;

    for (;;) {
        fputs("Enter a number (blank line to quit): ", stdout);
        len = getline(&linebuf, &linebufsz, stdin);
        if (len < 0) {
            perror("getline");
            return 1;
        }
        if (len < 2)
            return 0; /* empty line or EOF */

        /* chomp */
        if (linebuf[len-1]) == '\n')
            linebuf[len--] = '\0';

        /* convert and check for overflow */
        errno = 0;
        val = strtol(linebuf, &endp, 10);
        if ((ssize_t)(endp - linebuf) != len) {
            fprintf(stderr, "Syntactically invalid number: %s\n", linebuf);
            continue;
        }
        if (errno) {
            fprintf(stderr, "%s: %s\n", strerror(errno), linebuf);
            continue;
        }

        if (val % 100 == 0)
            printf("%ld is divisible by 100\n", val);
        else
            printf("%ld is not divisible by 100\n", val);
    }
}

I tested this on a machine where long is 64 bits wide, so it can do most but not all 19-digit numbers:

Enter a number (blank line to quit): 1234567890123456789
1234567890123456789 is not divisible by 100
Enter a number (blank line to quit): 12345678901234567890
Numerical result out of range: 12345678901234567890

Enter a number (blank line to quit): 9223372036854775807
9223372036854775807 is not divisible by 100
Enter a number (blank line to quit): 9223372036854775808
Numerical result out of range: 9223372036854775808

I suspect that on your computer long is only 32 bits wide, so the limit will instead be 2147483647 for you.

Upvotes: 0

Artem Yu
Artem Yu

Reputation: 4512

Your number just doesn't fit into long int type, so the actual number you get is not what you expect. Try using unsigned long long, but be aware that numbers greater than 2^64 - 1 won't fit anyway. Also, you should use scanf("%llu", &a) in this case

Upvotes: 7

Related Questions