Fun with bits...
cout
is printing the number as an Unsigned Long, all 64 bits are significant and print as unsigned binary integer (I think the format here would be %lu
).
printf(%u ...
treats the input as an normal unsigned integer (32 bits?). This causes bits 33 through 64 to drop off - leaving zero.
printf(%ld ...
treats the input as a 64 bit signed number and just prints it out as such.
The thing you might find confusing about the last printf
is that it gives the same absolute value as cout
, but with a minus sign. When viewing as an unsigned integer all 64 bits are significant in producing the integer value. However for signed numbers, bit 64 is the sign bit. When the sign bit is set (as it is in your example) it indicates the remaining 63 bits are to be treated as a negative number represented in 2's compliment. Positive numbers are printed simply by converting their binary value to decimal. However for a negative number the following happens: Print a negative sign, XOR bits 1 through 63 with binary '1' bits, add 1 to the result and print the unsigned value. By dropping the sign bit (bit 64) you end up with 63 '0' bits, XORing with '1' bits gives you 63 '1' bits, add +1 and the whole thing rolls over to give you an unsigned integer having bit 64 set to '1' and the rest set to '0' - which is the same thing you got with cout
BUT, as a negative number.
Once you have worked out why the above explanation is correct you should also be able to make sense out of this