#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 сделает это за вас под капотом.