В Java, когда используются битовые сдвиги, почему 1 << 32! = 1 << 31 << 1? - PullRequest
15 голосов
/ 31 марта 2009

int a = 1 << 32; int b = 1 << 31 << 1;

Почему == 1? б равен 0, как я ожидал.

Ответы [ 2 ]

23 голосов
/ 31 марта 2009

Все смены сделаны мод 32 для целых и мод 64 для длинных.

С раздел 15.19 спецификации :

Если повышен тип левой руки операнд int, только пять младшие биты правой руки операнд используется как сдвиг расстояние. Это как будто правая рука операнд был подвергнут побитовой логический оператор И & (§15.22.1) с значение маски 0x1f. Смена следовательно, фактически используемое расстояние всегда в диапазоне от 0 до 31, включительно.

Если повышенный тип левой руки операнд long, тогда только шесть младшие биты правой руки операнд используется как сдвиг расстояние. Это как будто правая рука операнд был подвергнут побитовой логический оператор И & (§15.22.1) с значение маски 0x3f. Смена следовательно, фактически используемое расстояние всегда в диапазоне от 0 до 63, включительно.

Что касается , почему язык был разработан таким образом - я не знаю, но C # имеет такое же дизайнерское решение. Вот что говорит аннотированная спецификация ECMA C #:

C # сознательно держит определенные реализацией поведения к miinimum. Они принимаются только тогда, когда влияние на производительность воздействия единообразное поведение было бы чрезмерным (например, для некоторого числа с плавающей точкой вопросы точности). Следовательно, размер каждый цельный тип точно указан, и набор символов исправлено в Unicode.

Для сменных операций тоже униформа поведение уточняется. Может быть достигается с помощью одного дополнительного инструкция (& 0x1F или & 0x3F), которая влечет лишь крошечные расходы на современные процессоры, тем более что это не справочная память. В отличие от операции с плавающей точкой, разница в поведении смены будет драматично, если оставить на прихоть процессоры; а не маленький разница в точности, полностью разные интегральные результаты будут производится.

При принятии этого решения комитет изученные справочные материалы для количество разных процессоров архитектуры. Есть немного последовательность в поведении за смену считает вне диапазона -32 .. + 32 для 32-битные операнды и соответственно -64 .. + 64 для 64-битных операндов.

(Вот список некоторых примеров.)

Мне кажется, это вполне разумное объяснение. Согласованность, безусловно, важна, и если было бы невозможно реализовать согласованное поведение различного в некоторых системах, я думаю, это разумное решение.

0 голосов
/ 01 апреля 2009

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

Например, IIRC, ARM-процессоры (32-битный ISA) занимают младший байт сдвигового регистра. (Сдвиги на самом деле не являются самостоятельными инструкциями для ARM).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...