Почему этот битовый сдвиг вправо не работает? - PullRequest
10 голосов
/ 25 февраля 2009

Может ли кто-нибудь объяснить мне, почему маска вообще не смещена вправо? Вместо этого 1 можно использовать что угодно, и результат будет таким же.

unsigned mask = ~0 >> 1;
printf("%u\n", mask);

Ответы [ 4 ]

26 голосов
/ 25 февраля 2009

Это проблема типа. Если вы приведете 0 к неподписанному, все будет хорошо:

unsigned mask = ~ (unsigned) 0 >> 1;
printf("%u\n", mask);

Редактировать по комментариям: или использовать буквенную запись без знака, что гораздо более кратко. :)

unsigned mask = ~0u >> 1;
printf("%u\n", mask);
13 голосов
/ 25 февраля 2009

Расширение знака

То, что происходит, ~0 - это int со всеми установленными битами (-1). Теперь вы сдвигаете вправо на 1; так как -1, расширение знака поддерживает самый высокий установленный бит, поэтому он остается подписанным (это не то, что вы ожидали) Затем он преобразуется в неподписанный, как вы ожидаете.

4 голосов
/ 25 февраля 2009

Попробуйте это:

unsigned mask = (unsigned) ~0 >> 1;
printf("%08x\n", mask);

RHS присвоения рассматривается как подписанное количество, если вы не разыгрываете его, что означает, что вы видели расширение знака без разыгрыша. (Я также изменил ваш оператор печати, чтобы отображать число в шестнадцатеричном формате, который мне легче декодировать.)

2 голосов
/ 25 февраля 2009

~ 0 это строка из них. Оператор >> сдвигает их, и в знаковом значении он сдвигает единицы в биты высшего порядка. Таким образом, вы можете сдвигать все, что хотите, результат не изменится.

...