Reputation: 137
I'm using Codeblocks and the GNU compiler on a Windows computer. When the compiler runs, it does so under the following conditions:
mingw32-gcc.exe -Wall -g -std=c11 <filename> -o obj\Debug\main.o
My code is as follows:
#include <stdio.h>
#include <limits.h>
int main()
{
printf("INTEGER min: %d\n", INT_MIN);
printf("INTEGER max: %d\n\n", INT_MAX);
printf("UNSIGNED INTEGER max: %u\n\n", UINT_MAX);
printf("LONG INTEGER min: %ld\n", LONG_MIN);
printf("LONG INTEGER max: %ld\n\n", LONG_MAX);
//printf("LONG LONG INTEGER min: %lld\n", LONG_LONG_MIN);
//printf("LONG LONG INTEGER max: %lld\n\n", LONG_LONG_MAX);
printf("UNSIGNED LONG INTEGER max: %lu\n\n", ULONG_MAX);
//printf("UNSIGNED LONG LONG INTEGER max: %lld\n", ULONG_LONG_MAX);
printf("\n");
return 0;
}
My output for this code:
INTEGER min: -2147483648
INTEGER max: 2147483648
UNSIGNED INTEGER max: 4294967295
LONG INTEGER min: -2147483648
LONG INTEGER max: 2147483648
UNSIGNED LONG INTEGER max: 4294967295
The lines referring to LONG LONG integers are commented out because the compiler was giving errors:
error: 'LONG_LONG_MIN' undeclared (first use in this function)
error: 'LONG_LONG_MAX' undeclared (first use in this function)
error: 'ULONG_LONG_MAX' undeclared (first use in this function)
However, while typing the code, CodeBlocks provided code hinting indicating that I could, in fact, use the LONG_LONG constants. Hence, I need answers for the following questions:
Thanks
Upvotes: 0
Views: 2221
Reputation: 13786
Besides limits.h on a system with specific implementation, also check out what the C standard defines the limits of the various integers:
The values given below shall be replaced by constant expressions suitable for use in #if preprocessing directives. Moreover, except for CHAR_BIT and MB_LEN_MAX, the following shall be replaced by expressions that have the same type as would an expression that is an object of the corresponding type converted according to the integer promotions. Their implementation-defined values shall be equal or greater in magnitude
(absolute value) to those shown, with the same sign.
-- number of bits for smallest object that is not a bit-field (byte)
CHAR_BIT 8
-- minimum value for an object of type signed char
SCHAR_MIN -127 // -(27 - 1)
-- maximum value for an object of type signed char
SCHAR_MAX +127 // 27 - 1
-- maximum value for an object of type unsigned char
UCHAR_MAX 255 // 28 - 1
-- minimum value for an object of type char
CHAR_MIN see below
-- maximum value for an object of type char
CHAR_MAX see below
-- maximum number of bytes in a multibyte character, for any supported locale
MB_LEN_MAX 1
-- minimum value for an object of type short int
SHRT_MIN -32767 // -(215 - 1)
-- maximum value for an object of type short int
SHRT_MAX +32767 // 215 - 1
-- maximum value for an object of type unsigned short int
USHRT_MAX 65535 // 216 - 1
-- minimum value for an object of type int
INT_MIN -32767 // -(215 - 1)
-- maximum value for an object of type int
INT_MAX +32767 // 215 - 1
-- maximum value for an object of type unsigned int
UINT_MAX 65535 // 216 - 1
-- minimum value for an object of type long int
LONG_MIN -2147483647 // -(231 - 1)
-- maximum value for an object of type long int
LONG_MAX +2147483647 // 231 - 1
-- maximum value for an object of type unsigned long int
ULONG_MAX 4294967295 // 232 - 1
-- minimum value for an object of type long long int
LLONG_MIN -9223372036854775807 // -(263 - 1)
-- maximum value for an object of type long long int
LLONG_MAX +9223372036854775807 // 263 - 1
-- maximum value for an object of type unsigned long long int
ULLONG_MAX 18446744073709551615 // 264 - 1
From http://www.iso-9899.info/n1570.html#5.2.4.2.1
Upvotes: 1
Reputation: 153417
Why do the integers and long integers have the same limits? Shouldn't the long integers have a larger range of values?
You have stepped into one of the hallmarks of the C language - its adaptability.
C defines the range of int
to be at least as wide as short
and the range of long
to be at least as wide as int
. All have minimum ranges.
Rather than precisely defined the range of short, int, long
, C opted for versatility. On OP's platform, the range of int
matches the range of long
(32-bit). On many embedded processors of 2016 (and home computers of the 70s,80s), the range of int
matches the range of short
(16-bit). On some platforms (64-bit) the range of int
exceeds short
, and narrower than long
. So directly to OP's question: int
does not always have the same range as long
.
The trick is that int
is not just another rung of the singed char, short, int, long, long long
ladder. It is the integer type. Given the usual integer promotions, all narrows types promote to int
. int
is often the processor's native bit width.
Most code has been written with int
as 32-bit and also a large percentage as 16-bit. With 64-bit processors, having int
as 64-bit is possible, but that leaves only 2 standard type for signed char, short
for 8, 16 and 32-bit.
Going forward, simple count on signed char
range <=
the short
range, short
range <=
the int
range, int
range <=
the long
range, etc. Also that signed char
is at least 8-bit, short, int
at least 16-bit, long
at least 32-bit, long long
at least 64-bit. If code needs explicit widths, use int8_t
, int16_t
, etc.
The fact that C is used 40+ years later attests that this versatility has/had merit.
[Discussion omits unsigned types, _Bool_t
and char
for brevity. Also omitted are rare non-power-of-2 types (9, 18, 24, 36 etc.)]
Upvotes: 2
Reputation: 93161
The constants are LLONG_MAX
, ULLONG_MAX
, etc.
As to why int
and long int
have the same value, blame the C standard: it does not define a fixed number of bits for each data type, only the minimum number of bits:
int
must be at least 16 bitslong int
must be at least 32 bitslong long int
must be at least 64 bitsThe exact number of bits differ from OS to OS.
#include <stdio.h>
#include <limits.h>
int main()
{
printf("INTEGER min: %d\n", INT_MIN);
printf("INTEGER max: %d\n\n", INT_MAX);
printf("UNSIGNED INTEGER max: %u\n\n", UINT_MAX);
printf("LONG INTEGER min: %ld\n", LONG_MIN);
printf("LONG INTEGER max: %ld\n\n", LONG_MAX);
printf("LONG LONG INTEGER min: %lld\n", LLONG_MIN);
printf("LONG LONG INTEGER max: %lld\n\n", LLONG_MAX);
printf("UNSIGNED LONG INTEGER max: %lu\n\n", ULONG_MAX);
printf("UNSIGNED LONG LONG INTEGER max: %llu\n", ULLONG_MAX);
printf("\n");
return 0;
}
On my Mac OS X, 64-bit, that prints:
INTEGER min: -2147483648
INTEGER max: 2147483647
UNSIGNED INTEGER max: 4294967295
LONG INTEGER min: -9223372036854775808
LONG INTEGER max: 9223372036854775807
LONG LONG INTEGER min: -9223372036854775808
LONG LONG INTEGER max: 9223372036854775807
UNSIGNED LONG INTEGER max: 18446744073709551615
UNSIGNED LONG LONG INTEGER max: 18446744073709551615
Edit: if you want to write portable code and have fixed-width integers, use stdint.h
:
#include <stdint.h>
printf("int64_t max : %lld\n\n", INT64_MAX); // 9223372036854775807
printf("uint64_t max: %llu\n\n", UINT64_MAX); // 18446744073709551615
Upvotes: 5
Reputation: 34145
The constants you're looking for are not called LONG_LONG_...
. Check your limits.h
header. Most likely you're after ULLONG_MAX
, LLONG_MAX
, etc.
Upvotes: 9