Last updated :
Posted :
There are three kinds of integer literals in c. They are the decimal, octal and hexadecimal. The integer literals can be of the int, long, and long long type, and they can be either signed, or unsigned.
There are three kinds of integer literals in c, they are the:
1
.
0
digit, for example 07
.
0x
,
or
0X
, for example 0xAA
.
/* ********** Available integer Literals **** Decimal : starts with a non zero digit. octal : starts with 0 hexadecimal : starts with 0x or 0X * ******************************************/ #include <stdio.h> /* include the stdio header, to use printf, to print formatted output .*/ #define decimalLiteral 10 // define a constant decimal integer literal 10 #define octalLiteral 010 // define an octal integer literal 10 #define hexadecimalLiteral 0x10 // define a hexadecimal integer literal 10 int main( int argc, char * argv[ ]){ int hexLiteralCapitalX = 0X10; /* assign to the variable hexLiteralCapitalX the hexadecimal integer literal 10 .*/ printf( "decimalLiteral is %d\n", decimalLiteral ); //decimalLiteral is 10 printf( "octalLiteral is %d\n", octalLiteral ); //octalLiteral is 8 printf( "hexadecimalLiteral is %d\n", hexadecimalLiteral ); //hexadecimalLiteral is 16 printf( "hexadecimalLiteral is %d\n", hexLiteralCapitalX ); //hexadecimalLiteral is 16 return 0;}
By default a decimal integer literal has the int type. If it is too large to fit in the int type, then it is checked against the long type. If it is too large to fit in the long type, then it is checked against the long long type. If it is still too large to fit in the long long type , then the compiler will check if it can fit in any implementation defined extended integer types, by applying the same rules described earlier, which is checking the next larger signed integer type that can hold this integer literal. If there is no type, that can hold this integer value, then it will have no type, and the result is undefined, so the compiler might throw an error.
/* The max integer values supported on this system are: INT_MAX 2147483647 INT_MIN -2147483648 LONG_MAX 9223372036854775807 LONG_MIN -9223372036854775808 LLONG_MAX 9223372036854775807 ULLONG_MAX 18446744073709551616 */ int main( int argc, char * argv[ ] ) { int anIntOne = 2147483647; /* 2147483647 is <= INT_MAX, as such it is considered to be an int .*/ int anIntTwo = 2147483648; /* compiler output: warning: implicit conversion from 'long' to 'int' changes value from 2147483648 to -2147483648 . 2147483648 is larger than INT_MAX, as such the integer literal 2147483648 is checked against the next larger integer type which is long. It can fit in the long type, as such it is of the long type. The declared variable anIntTwo is of the int type, as such the long integer literal 2147483648 is cast to int, and the result is -2147483648 .*/ int anIntThree = 9223372036854775807; /* compiler output: warning: implicit conversion from 'long' to 'int' changes value from 9223372036854775807 to -1. The integer literal has a value of 9223372036854775807 which is > INT_MAX and <= LONG_MAX, as such the integer literal 9223372036854775807 is considered to be of the long type. On this system LONG_MAX and LLONG_MAX have the same max value 9223372036854775807. As such the integer literal 9223372036854775807 will never have the long long type. The declared variable anIntThree is of the int type, as such the long integer literal 9223372036854775807 is truncated to the int type, and the resulting value is -1 .*/ int anIntFour = 9223372036854775808; /* compiler output: warning: integer literal is too large to be represented in type 'long' and is subject to undefined behavior interpreting as 'unsigned long'; warning: implicit conversion from 'unsigned long' to 'int' changes value from 9223372036854775808 to 0 When the integer literal value is larger than the max long long value that the system can have, and when there is no extended integer type that can store the integer literal value, then the integer literal has no type, and the behaviour is undefined. On this machine, long and long long have the same max limit, this is why the compiler says that the integer literal cannot be stored in the long type, and that the behaviour is undefined. The compiler decided to interpret the integer literal as an unsigned long. Since the declared variable is of type int, the unsigned long integer literal is first interpreted as a long integer literal, which is later on truncated to the int type, and the result of the truncation is 0.*/ int anIntFive = 18446744073709551618; /* compiler output error: integer literal is too large to be represented in any integer type When the integer literal value is larger than the max long long value that the system can have, and when there is no extended integral type that can hold this integer literal value, the behavior is undefined by the c standard. Some compilers might treat the integer literal as being an unsigned long long, as in the previous case of anIntFour, if it is still larger than unsigned long long, then the compiler issues an error .*/ int anIntSix = -2147483649; /* compiler output: warning: implicit conversion from 'long' to 'int' changes value from -2147483649 to 2147483647 For negative values, the compiler, first checks the positive value to determine its data type. Once the data type is determined, it performs, its negation to get the negative value. 2147483649 is larger than INT_MAX, as such it cannot be of the int type. The next larger type is checked which is the long type. 2147483649 can fit in the long type, as such it is of the long type. The negation of 2147483649 is -2147483649. The declared variable anIntSix is of the int type, as such the long integer literal -2147483649 is truncated to fit into int, and the result is 2147483647 .*/ return 0;}
The octal and hexadecimal integer literals have by default the int type. If they are too large to fit in the int type, they are first checked against the unsigned int type, if they are still too large to fit in the unsigned int type, then they are checked against the long type, next against the unsigned long type, after that against the long long type, and finally against the unsigned long long type.
If the value is still too large to fit, and the compiler defines some extended integer types, then the integer literal is checked against one of these extended integer types, by applying the same rules that are described earlier, which is first trying the signed type, and next the unsigned type. If it is still too large to fit, then this integer literal has no type, and the behaviour is undefined, so the compiler might throw an error.
/* The max possible integer values on this system are: INT_MAX 2147483647 0x7fffffff INT_MIN -2147483648 -0x80000000 UINT_MAX 4294967295 0xffffffff LONG_MAX 9223372036854775807 0x7fffffffffffffff LONG_MIN -9223372036854775808 -0x8000000000000000 ULONG_MAX 18446744073709551616 0x10000000000000000 LLONG_MAX 9223372036854775807 0x7fffffffffffffff LLONG_MIN -9223372036854775808 -0x8000000000000000 ULLONG_MAX 18446744073709551616 0x10000000000000000 */ int main( int argc, char * argv[ ] ){ unsigned int anIntOne = 0x7fffffff; /* 0x7fffffff is 2147483647 2147483647 <= INT_MAX as such it is considered to be an int .*/ unsigned int anIntTwo = 0xffffffff; /* 0xffffffff is 4294967295 , INT_MAX < 4294967295 <= UINT_MAX so 0xffffffff is treated as an unsigned int .*/ unsigned int anIntThree = 0x7fffffffffffffff; /* compiler output: warning: implicit conversion from 'long' to 'unsigned int' changes value from 9223372036854775807 to 4294967295 0x7fffffffffffffff is 9223372036854775807, UINT_MAX < 9223372036854775807 <= LONG_MAX, So the integer literal 0x7fffffffffffffff is treated as a long. anIntThree is of type unsigned int, as such the long integer literal 0x7fffffffffffffff is first treated as unsigned long, and next truncated to unsigned int, and the result is 4294967295 .*/ unsigned int anIntFour = 0x8000000000000000; /* compiler output: warning: implicit conversion from 'unsigned long' to 'unsigned int' changes value from 9223372036854775808 to 0 0x8000000000000000 is 9223372036854775808, LONG_MAX < 0x8000000000000000 <= ULONG_MAX so 0x8000000000000000 is treated as an unsigned long. anIntFour is of type unsigned int, as such the integer literal 0x8000000000000000 is truncated to the unsigned int type and the value is 0 .*/ unsigned int anIntFive = 0x10000000000000001; /* compiler output: error: integer literal is too large to be represented in any integer type When the value is larger than the max unsigned long long value that the system can have, and there is no extended integer type that can hold this value, the integer literal has no type, and the behaviour is undefined by the c standard. In this case the compiler raises an error. On this system, long and long long have the same max limit .*/ unsigned int anIntSix = -0x80000001; /* -0x80000001 is equal to -2147483649 . The C compiler first ignore the negative sign, and check only the absolute value of the integer literal to determine its type. After determining the data type, the compiler apply the negation operator, on the absolute value of the integer literal in the determined data type, to calculate its negation. 0x80000001 is larger than INT_MAX, 0x80000001 is a hexadecimal integer literal, as such the next type to check for is, the unsigned int type. 2147483649 is smaller than 0xffffffff, as such it fits the Unsigned int type. So it is of the unsigned int type. The negation of 2147483649 is calculated by the formula -2147483649 + 2^32 = 2147483647 . The declared variable anIntSix is of the unsigned int type, as such the calculated value is stored in anIntSix .*/ return 0; }
The
letter
l
or
L
,
ca be appended to an integer literal,
to state that it is of the
long type.
The letters
ll
,
or
LL
, can be appended to
an integer literal,
to indicate that it is of the
long long
type.
The same rules apply for a decimal integer literal, of the type long, or long long, as those that were described earlier in type resolution for the decimal kind, starting from long, or long long .
And the same rules apply for a hexadecimal, or an octal integer literal, of the type long, or long long, as those that were described earlier in type resolution for the hexadecimal and octal kinds, starting from long or long long.
/* The max possible integer value on this system are : INT_MAX 2147483647 0x7fffffff UINT_MAX 4294967295 0xffffffff LONG_MAX 9223372036854775807 0x7fffffffffffffff ULONG_MAX 18446744073709551616 0x10000000000000000 LLONG_MAX 9223372036854775807 0x7fffffffffffffff ULLONG_MAX 18446744073709551616 0x10000000000000000 The compiler also defines the extended integer type __int128 which is 128 bits long .*/ int main( int argc, const * argv[ ] ){ long aLongInteger = 2147483647l; /* 2147483647l <= INT_MAX, but the integer literal 2147483647l is of the type long since it has the l suffix appended .*/ long long aLongLongInteger = 9223372036854775807LL; /* 9223372036854775807LL <= LONG_MAX, but the LL suffix is used, as such the integer literal 9223372036854775807LL is of the Long Long type .*/ int anIntSix = 9223372036854775809L; /* compiler output: warning: integer constant is so large that it is unsigned warning: overflow in conversion from '__int128' to 'int' changes value from '9223372036854775809' to '1' 9223372036854775809L > LONG_MAX , hence the integer literal 9223372036854775809 is matched against the next larger integer type. long long has the same max value as long, so it is ignored. The compiler defines the extended integer type __int128 which is 128 bit long. It can store the integer literal 9223372036854775809. As such the integer literal is treated as __int128. The declared variable anIntSix is of type int, as such the integer literal 9223372036854775809 is truncated to int, and the value of the truncation is 1 .*/ return 0; }
The
letters u
or U
can be
appended to an integer literal, to specify that it is of the
type
unsigned int.
If it is too large to fit in an
unsigned int,
it is treated as an
unsigned long,
if it is still too large to fit in, it is treated as
unsigned long long,
if it is still too large and the compiler has an extended unsigned
integer type, that can hold this integer literal, it is treated of
that type, else this literal will have no type, and the behaviour
is undefined .
/* The max possible integer values on this system are : INT_MAX 2147483647 0x7fffffff UINT_MAX 4294967295 0xffffffff LONG_MAX 9223372036854775807 0x7fffffffffffffff ULONG_MAX 18446744073709551616 0x10000000000000000 LLONG_MAX 9223372036854775807 0x7fffffffffffffff ULLONG_MAX 18446744073709551616 0x10000000000000000 */ int main( int argc, char * argv[ ] ){ unsigned int anUnsingedIntOne = 2147483647u; /* 2147483647u<=INT_MAX, but the u suffix is used as such the integer literal is treated as an unsigned int, since it is less than UINT_MAX .*/ unsigned int anUnsingedIntTwo = 9223372036854775807u; /* 9223372036854775807u<=LONG_MAX, but the u suffix is used, as such the integer literal is treated as an unsigned long, since it is less than ULONG_MAX .*/ unsigned int anUnsingedIntThree = 18446744073709551617u; /* compiler output: error: integer literal is too large to be represented in any integer 18446744073709551617u > ULLONG_MAX, and there is no extended integer type, that can hold this integer literal value. As such this integer literal value has no type, and the behaviour is undefined by the c standard. The compiler raised an error .*/ return 0;}
The
letter
u
can be mixed, with both
the letters
L
and
LL
,
to specify that the integer literal is of type
unsigned long
UL
,
and
unsigned long long
ULL
.
The same rules apply on an
unsigned long ,
and an
unsigned long long,
as those described for an
unsigned int
, starting
unsigned long
, and
unsigned long long .
/* The max integer value on this system are : INT_MAX 2147483647 0x7fffffff UINT_MAX 4294967295 0xffffffff LONG_MAX 9223372036854775807 0x7fffffffffffffff ULONG_MAX 18446744073709551616 0x10000000000000000 LLONG_MAX 9223372036854775807 0x7fffffffffffffff ULLONG_MAX 18446744073709551616 0x10000000000000000 */ int main( int argc, char * argv[ ] ){ unsigned long unsignedLongInteger = 2147483647ul; /* 2147483647ul < INT_MAX, but the ul suffix is used, as such the integer literal 2147483647 is treated as an unsigned long, since it is less than ULONG_MAX .*/ unsigned long long unsignedLongLongInteger = 9223372036854775807LLU; /* 9223372036854775807LLU <= LONG_MAX, but the llu suffix is used, as such the integer literal 9223372036854775807 is treated as an unsigned long long, since it is less than ULLONG_MAX .*/ unsigned long long unsignedLongLongIntegerError = 18446744073709551616LLu; /* compiler output: error: integer literal is too large to be represented in any integer type 18446744073709551616LLu > ULLONG_MAX, the compiler does not define extended integer types, as such the integer literal has no type, and the behaviour is undefined. The compiler raised an error .*/ return 0;}