Запрос оператора тильды в 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),

Другие вопросы по тегам