Страницы

Поиск по вопросам

вторник, 23 октября 2018 г.

Неверный результат побитового НЕ

Почему возникает ошибка при выводе результата унарной операции ~? (должно было ведь получиться ~a = 0)
#include
int main (void) { unsigned char a = 0xff;
printf("a = %u
", a); printf("~a = %u
", ~a);
return 0; }
Результат (компилятор - Clang) :
a = 255 ~a = 4294967040


Ответ

Результат ~a имеет тип int, и вычисляется обращением битов после превращения a в int (integer promotions, так как int может представить все значения unsigned char, если не рассматривать редкий случай когда UCHAR_MAX > INT_MAX). В с11 (n1570)
The result of the ~ operator is the bitwise complement of its (promoted) operand (that is, each bit in the result is set if and only if the corresponding bit in the converted operand is not set). The integer promotions are performed on the operand, and the result has the promoted type. If the promoted type is an unsigned type, the expression ~E is equivalent to the maximum value representable in that type minus E
К примеру, на одной из возможных реализаций:
(~a) -> ~(FF) -> ~(00 00 00 FF) -> FF FF FF 00 = -256
Затем %u интерпретирует int как unsigned int, поэтому для примера выше: printf() получает -256 (FF FF FF 00) и выводит 4294967040 (34 32 39...).
0 вы получите, если (~a) назад в unsigned char превратить:
unsigned char b = ~a;
в этом случае -256 в ноль превращается (§6.3.1.3/2) так как вычисления по модулю UCHAR_MAX+1 происходят (UCHAR_MAX=255 здесь). printf("%u", b) выведет 0
Аналогично, в случае с %hhu: printf() получает int (FF FF FF 00) и интерпретирует его как unsigned char для печати:
#include
int main(void) { unsigned char a = 0xff, b = ~a; printf("a=%d b=%d ~a=%d
", a, b, ~a); printf("a=%u b=%u ~a=%u
", a, b, ~a); printf("a=%hhu b=%hhu ~a=%hhu
", a, b, ~a); }
Результат
a=255 b=0 ~a=-256 a=255 b=0 ~a=4294967040 a=255 b=0 ~a=0

Комментариев нет:

Отправить комментарий