user1002327
user1002327

Reputation: 533

Comparison between big numbers doesn't seem to work

The program I wrote takes two numbers and makes a division and a modulo operation.

The code is

#define ADDRESS_SPACE 4294967295
int main (int argc, char *argv[]) {
    long int pagesize = atoi(argv[1]), virtaddr = atoi(argv[2]);

    if (virtaddr >= ADDRESS_SPACE) {puts("Address is too large"); return 1;}

    printf("%lu\n", virtaddr);
    printf("%lu\n", ADDRESS_SPACE);
    printf("Page = %lu\nOffset = %lu\n", virtaddr/pagesize, virtaddr%pagesize);
    return 0;
}

And doing ./page 1024 9999999999999999999999999999999999999999999999 gives the following output

18446744073709551615
4294967295
Page = 0
Offset = 18446744073709551615

If virtaddr is bigger than ADDRESS_SPACE, why isn't the if statement working? I know there's an overflow, but printing the variables doesn't show any error and they are still numbers (the maximum value a long int can take).

Upvotes: 0

Views: 598

Answers (3)

Mark Ransom
Mark Ransom

Reputation: 308520

18446744073709551615 is the unsigned version of -1. virtaddr is signed but you displayed it as unsigned; of course -1 is going to be less than any valid positive number.

Upvotes: 1

Ed Heal
Ed Heal

Reputation: 60027

Because atoi converts from ASCII to ints and not to long ints and also 9999999999999999999999999999999999999999999999 is far to big to be converted into an int.

Try using sscanf for the string conversion and also try a more reasonable number.

Upvotes: 2

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726987

atoi returns INT_MAX when the number is out of range. Comparing a 32-bit int to 4294967295 is always false, because INT_MAX is roughly two times smaller. If you use strtoll instead of atoi, your solution will work, because the result will be in the range of long long. Alternatively, you could use INT_MAX instead of ADDRESS_SPACE.

Upvotes: 1

Related Questions