Запрос оператора тильды в C работает по-другому
Я сталкивался с этим вопросом. Что выводится этот код C?
#include <stdio.h>
int main()
{
unsigned int a = 10;
a = ~a;
printf("%d\n", a);
}
Я знаю, что делает оператор тильды, теперь 10 можно представить как 1010 в двоичном формате, и если я поразрядно не это, я получаю 0101, поэтому я не понимаю вывод -11. Кто-нибудь может объяснить?
3 ответа
Побитовое отрицание не приведет к 0101
, Обратите внимание, что int содержит не менее 16 бит. Итак, для 16 битов он сгенерирует:
a = 0000 0000 0000 1010
~a = 1111 1111 1111 0101
Таким образом, мы ожидаем увидеть большое число (с 16 битами, которое будет 65'525), но вы используете %d
как спецификатор формата. Это означает, что вы интерпретируете целое число как целое число со знаком. Теперь целые числа со знаком используют двухкомпонентное представление [wiki]. Это означает, что каждое целое число, в котором установлен старший бит, является отрицательным, и, кроме того, в этом случае значение равно -1-(~x)
, так -11
, Если указатель был %u
тогда формат будет целым без знака.
РЕДАКТИРОВАТЬ: как @R. говорит, %d
Правильно определяется только для целых чисел без знака, если они также находятся в диапазоне целых чисел со знаком, вне зависимости от реализации.
Это неопределенное поведение, так как "%d"
для целых чисел со знаком; для неподписанных используйте "%u"
,
В противном случае, обратите внимание, что отрицательные значения часто представлены как дополнение к двум; Так -a == (~a)+1
или наоборот: (~a) == -a -1
, Следовательно, (~10)
такой же как -10-1
, который -11
,
Спецификатор формата для беззнакового десятичного целого числа: %u
, %d
для подписанного десятичного целого числа.
printf("%d\n", a)
переводит a
как подписанный инт. Ты хочешь printf("%u\n", a)
,