сложность понимания того, что подпись не

#c #bitwise-operators

#c #побитовые операторы

Вопрос:

У меня возникли проблемы с пониманием, почему c равен -61 в следующей программе:

    main() {
       unsigned int a = 60;     // 60 = 0011 1100   
       unsigned int b = 13;     // 13 = 0000 1101
       int c = 0;           
       c = ~a;          //-61 = 1100 0011
       printf("Line 4 - Value of c is %dn", c );
   }
  

Я понимаю, как работает оператор NOT в 0011 1100 (решением является 1100 0011). Но я не уверен, почему десятичное число увеличивается на 1. Является ли это своего рода преобразованием типа из unsigned int (из a) в signed int (из c)?

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

1. Вот как работает нотация дополнения two.

2. Читать en.wikipedia.org/wiki/Two’s_complement

3. 11111111 является -1 , 00000000 является 0 .

Ответ №1:

Преобразование из положительного числа в отрицательное в дополнении twos (стандартный подписанный формат) представляет собой побитовую инверсию и добавление единицы.

Обратите внимание, что для простоты я использую один байт со знаком.

 So if 60 = 0011 1100
Then c   = 1100 0011   1
         = 1100 0100
  

И для байта со знаком старший бит отрицательный,
итак

 c = -128   64   4 = -60
  

Вам нужно добавить 1, чтобы учесть тот факт, что старший бит равен -128, а наибольшее положительное число равно 0111 1111 = 127. Все отрицательные числа имеют значение 1 для -128, которое необходимо компенсировать.

Это легко увидеть, если посмотреть на преобразование 0 в -0. Инвертируйте 00000000, и вы получите 11111111, а добавление единицы возвращает вас к 00000000. Проделайте то же самое с 1 к -1, и вы получите 11111111 — максимально возможное отрицательное число.

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

1. Хороший ответ. Двойное дополнение может показаться сложным и странным способом работы с числом со знаком, но на самом деле это очень умная кодировка, которая упрощает проектирование процессора. Это позволяет простой схеме двоичного сумматора без знака работать независимо от знака добавляемых величин и устраняет двусмысленность наличия как положительного, так и отрицательного нулевого значения.

2. не могли бы вы разъяснить мне пару вещей: 1) Я понимаю, как сделать комплимент 2, но зачем мы это делаем? Каким образом дополнение 2 связано с оператором NOT? 2) Я понимаю, откуда берутся эти цифры: c = -128 64 4 = -60, но ответ — c = -61. Откуда берется это вычитание (или добавление -1)?

3. Итак, причина, по которой c равен -61, а не -60, заключается в том, что оператор NOT фактически не преобразует положительное значение в отрицательное, он просто переворачивает биты. Это только половина процесса, чтобы получить значение от 60 до -60, другая половина — добавление 1 после переключения битов. Итак, c = ~ a 1 — это то, как вы могли бы «вручную» выполнить преобразование двоек в дополнение, но c = -1 * a сделает это за вас под капотом.