How does printf ("% c \ n", ~ ('C' * - 1)) evaluate to c?
In C, 'C'
there is int
, it is a small integer with a value 67
(assuming ASCII). You can get each step:
#include<stdio.h>
int main()
{
printf("%d\n", 'C'); //67
printf("%d\n", 'C' * -1); //-67
printf("%d\n", ~('C' * - 1)); //66
printf("%c\n",~('C' * -1)); //B
return 0;
}
In 2's complement, the value ~(-67)
is 66
.
source to share
The only important part is the expression:
~('C' * -1)
Let's break it down:
-
'C'
ASCII code 67. -
('C' * -1)
- -67. - -67 in binary, 10111101
- Bitwise negation of this (s
~
) and you have 01000010, which is 66. - 66 is the ASCII code for "B".
More generally, most computers use " two's complement " arithmetic, where a numeric negation followed by a bitwise negation is equivalent to subtracting 1. And, of course, B
less than C
ASCII.
On a computer that does not use two's complement, the result may be different. Such computers are rare.
source to share
It is well known that "making a number negative" (multiplying it by -1
) in two's complement is equivalent to inverting its bit representation ( ~
) and adding one ( +1
). So the above is equivalent ~(~'C' + 1)
, which in turn is equivalent to a simple decrement if the original number, as here, the ASCII code 'C'
, was odd.
That is, if LSB is installed 'C'
:
- LSB is
~'C'
not installed, which means that - after adding one (
~'C' + 1
) LSB is set again. - Now, inverting the whole expression (
~(~'C' + 1)
) will give us the original number - only when the LSB is no longer set, because it was set before the final inversion (which inverted the LSB like any other bit).
source to share