There are 2 conversion specifiers for scanf
for reading decimal numbers. u
reads an unsigned decimal integer - into a variable of unsigned integer type, and d
reads a signed decimal integer (into a variable of signed integer type). When reading signed decimal integer, the maximum for a 64-bit 2's complement number would be 2 ** 63 - 1
i.e. 9223372036854775807
. When a number exceeding this is matched, scanf
would still match it, but set the corresponding argument to the maximum value.
For unsigned 64-bit, the maximum would be 2 ** 64 - 1
. 18446744073709551610
would work for unsigned input, but you need the signed number for which 0xfffffffffffffffa
is the 2's complement representation. It is actually
>>> 0xfffffffffffffffa - 2 ** 64
-6
because the negative numbers are converted to unsigned by repeatedly adding or subtracting one larger than the maximum value until the value fits within the range - we now invert the operation and get -6
.
Note that it is not correct to scanf into an object using %ld
and then printf its value using %lx
as you seem to do, unless the variable is a signed int
and printf
invocation has a cast to the argument to unsigned
- because %lx
requires an unsigned long
int! If your compiler does not warn about it, then do add a switch such as -Wall
to enable extra diagnostics.