Because an integer constant in C is treated as, from the standard, "the first of the corresponding list in which its value can be represented".
The list for a non-suffixed decimal integer is:
int;
long int; and
long long int.
Unless your long long int types are the full 128 bits, that value won't fit. The standard allows for an implementation to fix this by virtue of the text (my emphasis):
If an integer constant cannot be represented by any type in its list, it may have an extended integer type, if the extended integer type can represent its value.
However, the use of the word "may" means that an implementation is not required to do this. You'd think it would make sense for a compiler with an extended type to provide a way of creating a constant of that type(1). Unfortunately, gcc appears not to do this, meaning you'll have to do some trickery along the lines of (check those digit counts, I'm not guaranteeing they're correct, just showing you the ugly nature of the workaround):
// long long int can go to 9223372036854775807,
// so break into chunks of 15.
__int128 a = 113427455;
a *= 1000000000000000; // 1e15
a += 640312821154458;
a *= 1000000000000000;
a += 202477256070485;
Alternatively, if you want to keep the number together and don't mind a small performance hit, you can use a function to build it at runtime, as per the example program below:
int Mk128(char *str, __int128 *p128) {
// Handle sign.
__int128 mult = 1;
if (*str == '-') {
mult = -1;
str++;
}
// Collect digits into number, handling grouping.
*p128 = 0;
while (*str != '\0') {
if (*str >= '0' && *str <= '9') {
*p128 = *p128 * 10 + *str - '0';
} else if (*str != ',' && *str != ' ' && *str != '.') {
return 0;
}
str++;
}
// Adjust for sign and return.
*p128 *= mult;
return 1;
}
#include <stdio.h>
// Recursive printer for large numbers, with grouping.
void print128(__int128 x, char *sep) {
// Handle negatives.
if (x < 0) {
putchar('-');
print128(-x, sep);
return;
}
// Print the top section, we're on the last recursion.
if (x < 1000) {
printf("%d", (int)x);
return;
}
// Otherwise recurse, then print this grouping.
print128(x / 1000, sep);
printf("%s%03d", sep, (int)(x % 1000));
}
// Test harness, just provide test data as arguments.
int main(int argc, char *argv[]){
__int128 a;
puts("=====");
for (int i = 1; i < argc; i++) {
puts(argv[i]);
if (! Mk128(argv[i], &a)) {
puts("*** Failed to make big int");
} else {
print128(a, ",");
putchar('\n');
}
puts("=====");
}
return 0;
}
This allows a string to be used with the following properties:
It can have either no, or one, leading - sign. If you want a positive number, just leave it off the -, no leading + allowed. This is basically how most people would write an integer constant in their code.
It can have spaces, commas, or periods, interspersed with the digits in any manner, but intended to allow for grouping of digits as per the sample run below. The periods are to cater for the Euro habit of swapping commas and periods for grouping and decimal points.
It also has a recursive print function so you can test it, used by the main function to show that the evaluation of the strings has worked.
A sample run:
pax:~> ./testprog 12345 -77 '-12.345,111,111.678.734.333,222 555 777' hello
=====
12345
12,345
=====
-77
-77
=====
-12.345,111,111.678.734.333,222 555 777
-12,345,111,111,678,734,333,222,555,777
=====
hello
*** Failed to make big int
=====
(1) There are some subtle interactions in the standard that make this difficult. Specifically, the [u]intmax_t types are supposed to be able to handle any of the integral types so, in cases where they remain at 64-bit, the 128-bit value is not actually considered an extended integer type, but rather a non-standard extension.
GCC actually calls this out in their documentation:
GNU C provides several language features not found in ISO standard C.
If it was an extended integer type, it would be covered by the standard.