Почему этот побитовый сдвиг-правый кажется неработоспособным?
Может кто-нибудь объяснить мне, почему маска вообще не смещена вправо? Вы можете использовать что-либо вместо этого 1, и результат будет таким же.
unsigned mask = ~0 >> 1;
printf("%u\n", mask);
Ответы
Ответ 1
Это проблема типа. Если вы отбрасываете 0 в unsigned, это будет хорошо:
unsigned mask = ~ (unsigned) 0 >> 1;
printf("%u\n", mask);
Редактировать в комментариях: или использовать нотацию беззнакового литерала, что намного более красноречиво.:)
unsigned mask = ~0u >> 1;
printf("%u\n", mask);
Ответ 2
Расширение знака
Что происходит ~0
- это int со всеми установленными битами (-1
). Теперь вы сдвигаетесь вправо на 1
; так как он -1
, расширение знака сохраняет самый старший бит, поэтому он остался подписанным (это не то, что вы ожидали). Затем он преобразуется в unsigned, как вы ожидаете.
Ответ 3
Попробуйте следующее:
unsigned mask = (unsigned) ~0 >> 1;
printf("%08x\n", mask);
RHS присваивания рассматривается как подписанное количество, если вы не произнесете его, а это означает, что вы видите расширение знака без трансляции. (Я также изменил ваш оператор печати, чтобы отобразить число в шестнадцатеричном формате, которое мне легче декодировать.)
Ответ 4
~ 0 - строка из них. Оператор → сдвигает их, и в значении знака он сдвигает их в биты более высокого порядка. Таким образом, вы можете переместить все, что хотите, результат не изменится.