В Java, при использовании сдвигов разряда, почему делает 1 <<32! = 1 <<31 <<1?

Невозможно унаследовать от вашего контроллера сохранение атрибутов и непосредственное изменение только тела (по крайней мере, не в чистом виде). ​​

Лучший вариант - добавить промежуточный слой (абстрактный класс) и использовать его в вашем контроллере. Чем другие пользователи могут реализовать абстрактный класс (не контроллер напрямую) со своей собственной логикой.

15
задан CookieOfFortune 31 March 2009 в 19:14
поделиться

2 ответа

Все сдвиги сделаны модификация 32 для ints и модификации 64 для longs.

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

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

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

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

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

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

В принятии этого решения комитет изучил ссылочные материалы для многих различных архитектур процессора. Существует мало непротиворечивости в поведении для количеств сдвига вне диапазона-32.. +32 для 32-разрядных операндов, и соответственно-64.. +64 для 64-разрядных операндов.

(Существует затем список некоторых примеров.)

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

23
ответ дан 1 December 2019 в 03:15
поделиться

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

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

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

0
ответ дан 1 December 2019 в 03:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: