Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do we define INT_MIN as -INT_MAX - 1? [duplicate]

AFAIK this is a standard "idiom"

#  define INT_MIN   (-INT_MAX - 1)  
#  define INT_MAX   2147483647    

Question: Why is the definition of INT_MIN not as -2147483648?

like image 427
Cratylus Avatar asked Sep 23 '14 20:09

Cratylus


People also ask

What is INT_MIN INT_MAX?

INT_MAX is a macro that specifies that an integer variable cannot store any value beyond this limit. INT_MIN specifies that an integer variable cannot store any value below this limit. Values of INT_MAX and INT_MIN may vary from compiler to compiler.

What is INT_MAX +1 in C++?

Typically, integers are stored as 4 bytes (32 bits). This means that in almost all machines, the maximum integer value will be 2^(31) - 1 = +2147483647.

Why is int min bigger than int max?

It's because there is only one zero, not a +0 and a -0 like in ones-complement.


1 Answers

Because 2147483648 is a long value as it does not fit in an int (in common system with 32-bit int and 64-bit long, on system with 32-bit long it is of type long long). So -2147483648 is of type long, not int.

Remember in C, an unsuffixed decimal integer constant is of the first type int, long or long long where it can be represented.

Also in C -2147483648 is not a integer constant; 2147483648 is an integer constant. -2147483648 is an expression formed with the unary operator - and the integer constant 2147483648.

EDIT: if you are not convinced -2147483648 is not of type int (some people in the comments still seem to doubt), you can try to print this:

printf("%zu %zu\n", sizeof INT_MIN, sizeof -2147483648);

You will most likely end up with:

4 8

on common 32 and 64-bit systems.

Also to follow a comment, I'm talking about recent C Standard: use c99 or c11 dialect to test this. c89 rules for decimal integer constant are different: -2147483648 is of type unsigned long in c89. Indeed in c89 (it is different in c99, see above), a unsuffixed decimal integer constant is of type int, long or unsigned long.

EDIT2: @WhozCraig added another example (but for C++) to show -2147483648 is not of type int.

The following example, though in C++, drives home this point. It was compiled with a 32-bit architecture g++. Note the type info gathered from the passed parameter deduction:

#include <iostream>
#include <climits>

template<typename T>
void foo(T value)
{
    std::cout << __PRETTY_FUNCTION__ << '\n';
    std::cout << value << '\n';
}

int main()
{
    foo(-2147483648);
    foo(INT_MIN);
    return 0;
}

Output

void foo(T) [T = long long]
-2147483648
void foo(T) [T = int]
-2147483648
like image 186
ouah Avatar answered Sep 19 '22 15:09

ouah