Почему в Java и C # есть операторы битовых сдвигов? - PullRequest
5 голосов
/ 01 октября 2010

Разница между целочисленным умножением (временным забыванием о делении) все еще в пользу сдвига и, если да, насколько велика разница?

Это просто кажется такой низкоуровневой оптимизацией, даже если вы хотели, чтобы (C # / Java) компилятор байт-кода или jit его перехватывали в большинстве случаев?

Примечание. Я протестировал скомпилированный вывод для C # (с компилятором gmcs Mono C # версии 2.6.7.0), и в примерах умножения не использовался сдвиг для умножения даже при умножении на кратное 2.

C # http://csharp.pastebin.com/hcrRnPrb

КСС http://csharp.pastebin.com/0js9F2c1

* * 1012 P.S. Я забыл, как может быть полезно использовать его в байтах, но все еще возникают проблемы при использовании его для чисел.

Ответы [ 8 ]

22 голосов
/ 01 октября 2010

Первая причина:

Иногда - чаще всего - вы хотите трактовать целое число как число .Иногда целое число является удобным способом представления набора битов.

Умножение - это операция над числами.

Сдвиг - это операция с набором битов.

То, что между результатами умножения и результатами существует связьсмещения не особо актуально.Операции логически отличаются.

Вторая причина:

C # и Java были разработаны, чтобы быть знакомыми разработчикам C, хотя и на поверхностном уровне.Поэтому общие идиомы из C были включены в C # и Java.

12 голосов
/ 01 октября 2010

Если бы я хотел умножить число на 4, я бы написал * 4. Если мое намерение состоит в том, чтобы сдвинуть влево несколько битов на 2 позиции, я бы написал << 2.

По вопросу:

Почему в Java и C # есть операторы битовых сдвигов?

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

Конечно, я мог бы напечатать * 2 и т. Д., Но то, что я действительно хочу сделать , это сдвинуть биты.

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

Кроме того, есть некоторые тонкости операций сдвига, когда вы не хотите, чтобы он вел себя как целое число, особенно при работе с краями ... правила для что происходит, когда вы слегка сдвигаете карту влево или биты в карты (-ve vs + ve и т. д.) хорошо понятны, но очень важны. Аналогично, поведение целочисленного умножения checked / unckecked иногда очень важно.

8 голосов
/ 01 октября 2010

Вы правы, если операторы сдвига используются только в качестве альтернативы умножениям, это следует оставить компилятору.

Полагаю, вы пропустили такие приложения, как:

  • Шифрование / дешифрование
  • Расчет CRC
  • Работа с растровыми изображениями (графика, блокировки базы данных)
  • Сжатие / декомпрессия
  • Настройка данных для аппаратных регистров
  • Изменить кодировку

и многое другое для правильной реализации без встроенного кода.

1 голос
/ 01 октября 2010

В сущности, вы спрашиваете не о том, почему в C # / Java есть операторы смещения битов, а о том, почему компилятор javac не оптимизирует умножения и деления со степенью двойки на биты.

Реакция коленного толчка на это заключается в том, что умножение и деление имеют другую семантику, чем битовые сдвиги, поэтому он не отображает 100% для замены операций.

Кроме того, вы забыли дополнительный этап компиляции, который происходит в JIT (HotSpot), где происходят все виды дополнительных оптимизаций. Откровенно говоря, нет необходимости оптимизировать этот конкретный шаг, в отличие от C, где код соответствует тому, как его генерирует компилятор.

0 голосов
/ 01 октября 2010

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

0 голосов
/ 01 октября 2010

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

0 голосов
/ 01 октября 2010

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

Посмотрите это учебное пособие - большинство примеров получены из математических задач.Если вы просто делаете сайт или приложение с графическим интерфейсом, вам, вероятно, не нужно переходить, но иногда вы действительно делаете это ...

0 голосов
/ 01 октября 2010

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

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

...