Что именно происходит с ~ (char) ((unsigned char) ~ 0 >> 1)? - PullRequest
1 голос
/ 29 марта 2019

Я не понимаю, что именно происходит в этой комбинации унарных операторов.Я знаю, что, когда вы наберете его, он в конечном итоге выдаст наименьшее значение знака со знаком, я не понимаю, как именно.

То, что я думаю, это решение ========================================================================

~ - это унарный оператор, который фактически означает то же самое, что и логический операнд «НЕ», верно?

Значит, не символ означает что?Все в char уменьшается до 0?

Разве символ не приводится к неподписанному символу?

затем мы приводим char к unsigned, но все, что не равно 0, перемещается на 2 ^ 1, поскольку >> 1 - это то же самое, что и 2 ^ 1, верно?

========================================================================

#include <stdio.h>

int main(){
printf("signed char min = %d\n", ~(char)((unsigned char) ~0 >> 1)); 

return 0;
}

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

Ответы [ 2 ]

1 голос
/ 29 марта 2019

~ не является логическим НЕ, это поразрядным НЕ, поэтому он переворачивает каждый бит независимо.

~0 это все 1 битПри приведении его к знаковому символу и сдвиге вправо получается первый бит 0. При приведении к знаковому символу и применении поразрядно НЕ получается первый бит 1, а остальные 0, что является минимальным значением дополнения до двух * 1010.* integer (предполагается, что здесь используется дополнение до двух, что не гарантируется стандартом).

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

1 голос
/ 29 марта 2019

Этот код выглядел знакомым, поэтому я искал свою древнюю почту и нашел этот макрос:

#define MSB(type) (~(((unsigned type)-1)>>1))

в подписи Марка С. Брадера.

Возвращает значение указанного целочисленного типа, все биты которого равны нулю, кроме самого старшего бита.

  • (unsigned char)-1 производит # FF
  • (#FF)>>1 производит # 7F
  • ~(#7F) производит # 80

Так получилось, что # 80 оказалось наименьшим отрицательным значением для данного типа (хотя в теории C не требуется использовать дополнение 2s для хранения отрицательных целых чисел).

EDIT:

Первоначальный MSB (тип) был предназначен для получения значения, которое будет присвоено переменной типа «тип».

Как указывает @chux, если он используется в других контекстах, он может расширить дополнительные биты влево.

Более правильная версия:

#define MSB(type) ((unsigned type)~(((unsigned type)-1)>>1))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...