简体   繁体   中英

Why the sequence from the bitwise operator(~) would be this? Is that broken?

#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? /

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM