-1

I am debugging a C program which accepts input through scanf() using %ld as the format.

I need to send an input such that it is equal to 0xfffffffffffffffa.

If I convert the above hex value to decimal using Python, I get: 18446744073709551610 as shown below:

>>> a = 0xfffffffffffffffa
>>> a
18446744073709551610L

However, when I debug the program, I can see that the value was read by the program as: 0x7fffffffffffffff

So, is there a way to generate a decimal such that scanf() reads it as 0xfffffffffffffffa instead of 0x7fffffffffffffff?

M.M
  • 138,810
  • 21
  • 208
  • 365
Neon Flash
  • 3,113
  • 12
  • 58
  • 96

1 Answers1

0

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.