#include <stdio.h>
#include <stdlib.h>
int main() {
unsigned char a=100,b=50;
printf("%d & %d = %d\n",a,b,a&b);
printf("%d | %d = %d\n",a,b,a|b);
printf("%d ^ %d = %d\n",a,b,a^b);
printf(" ~%d = %d\n",a, ~a); /*the out come of this line would be this: ~100 = -101 */
printf(" %d >> 2= %d\n",a, a>>2);
printf(" %d << 2= %d\n",a, a<<2);
system("pause");
return 0;
}
/the out come should be 155 ,isn't it?/
CodePudding user response:
According to the standard, the operand of ~
will undergo integral promotion. So here we will first promote a
to int
.
[expr.unary.op]: The operand of ~ shall have integral or unscoped enumeration type; the result is the ones' complement of its operand. Integral promotions are performed.
If int
is 4 bytes (for example), the value of the promoted a
is 0x00000064
. The result of ~a
is 0xFFFFFF9B
, which is exactly -101
(If using two's complement to represent integers).
Please note that although variadic arguments will undergo integral promotion, here ~a
is of type int
and no additional promotion is required.
CodePudding user response:
100 = 0x64
~0x64 = 0x9B
In printf(" ~%d = %d\n",a, ~a);
, the second format specifier %d
expects a signed integer
, so the result 0x9B will be extended to a signed integer
. The MSB of 0x9B is 1, so it is regarded as a negative value
.
0x9B ---extends to>>> 0xFFFFFF9B = -101
If you want the result as 155
, you need a unsigned
cast so the 0x9B
will be extended to 0x0000009B
.
#include <stdio.h>
int main() {
unsigned char a = 100, b = 50;
printf(" ~%d = %d\n", a, ~a);
printf(" ~%d = %d\n", a, (unsigned char)~a);
return 0;
}
This will give result:
gcc test.c
./a.out
~100 = -101
~100 = 155