Учебник по битовому смещению Java?

Я был бы благодарен за хороший учебник, который объясняет новичкам в Java, как в Java работают все «битовые сдвиги».

Я всегда натыкаюсь на это, но никогда не понимал, как это работает. Он должен объяснять все операции и концепции, которые возможны при смещении байтов/битовых манипуляциях в java.

Это просто пример того, что я имею в виду (но я ищу учебник, который объясняет все возможные операции):

byte b = (byte)(l >> (8 - i << 3));

person Markus    schedule 06.06.2011    source источник
comment
Это битовый сдвиг, а не байтовый сдвиг.   -  person Oded    schedule 06.06.2011
comment
спасибо, обновил шапку (вы были быстрее ;-)   -  person Markus    schedule 06.06.2011
comment
Возможно, вы захотите взглянуть на эту страницу: stackoverflow.com/questions/141525/   -  person Mike Kwan    schedule 06.06.2011
comment
Для всех заинтересованных, помимо ответов ниже, ссылка от Майка выше абсолютно достойна прочтения!   -  person Markus    schedule 06.06.2011


Ответы (8)


Итак, официальное руководство по Java Побитовые операторы и операторы побитового сдвига описывает фактические операции, доступные в Java, и способы их вызова.

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

Обратите внимание, что часто битовая перестановка приводит к повышению эффективности за счет ясности. Например, a << 1 обычно совпадает с a * 2, но, возможно, менее понятен. Повторяющиеся операции XOR могут поменять местами два числа без использования временной переменной, но обычно считается, что лучше написать код более четко с временной переменной (или, что еще лучше, в служебном методе). Так что в этом отношении трудно привести отличные примеры, потому что вы вряд ли добьетесь чего-то нового или глубокого на уровне архитектуры; все дело в низкоуровневых деталях. (И я полагаю, что огромное количество случаев использования битового сдвига «в дикой природе» являются примерами преждевременной оптимизации.)

person Andrzej Doyle    schedule 06.06.2011
comment
С другой стороны, мне больше нравится 1 << i, чем (int)Math.pow(2,i) (для i в диапазоне 0 .. 31). - person Paŭlo Ebermann; 06.06.2011
comment
@Paŭlo: На самом деле это хороший пример моей точки зрения. Хотя Java многословна, я предпочитаю здесь Math.pow, потому что она объявляет намерение. Тот факт, что целые числа реализованы как двоичные за кулисами, делает арифметику степени двойки выражаемой меньшим количеством символов (и, возможно, циклов ЦП), поскольку << является аппаратной аварией. В общем, побитовые операторы должны (IMHO) использоваться только тогда, когда объект действительно представляет собой последовательность байтов, и вы делаете что-то вроде хэширования/криптографии/сжатия/и т. д. - иначе вы рискуете создать код только для записи. - person Andrzej Doyle; 06.06.2011
comment
Если бы там был оператор целочисленного возведения в степень, я бы тоже предпочел его. Но это не так, и Math.pow определяется на double значениях. (И поскольку Java уже использовала ^ для побитового/логического исключающего ИЛИ, мы не получим такой оператор.) Я думаю, что можно разрешить только 1 << i (возможно, с комментарием // 2^i или вроде того). - person Paŭlo Ebermann; 06.06.2011
comment
Побитовые операции полезны для таких вещей, как цвета RGB, созданные BufferedImages. - person Thijser; 06.02.2014
comment
Что касается крутых операций, самая удобная, которую я когда-либо находил, — это замена XOR — она позволяет переключать значения двух переменных, не выделяя больше памяти. В Java это будет X = X^Y; У = У ^ Х; Х = Х^Y; Приложения могут показаться ограниченными, но если вы имеете дело со встроенными системами с ограничениями памяти или хотите серьезно оптимизировать производительность, у него есть свое применение. - person mdhansen; 06.04.2016

При использовании оператора сдвига будьте очень осторожны, чтобы не повторить распространенную ошибку!!

Как следует из следующего сообщения SO, автор принятого ответа упоминает:

"В некоторых языках применение операторов сдвига к любому типу данных, меньшему, чем int, автоматически изменяет размер операнда, чтобы он был int."

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

Дан байт со следующим битовым шаблоном:

1001 0000

Когда я попытался сдвинуть бит на 4 и присвоил ему значение int, например:

int value = byteValue >>> 4;

Я бы ожидал иметь:

0000 1001   (or a value of 9)

Но я бы получил ОГРОМНОЕ число! Это связано с тем, что byteValue приводится к типу int ДО операции сдвига битов, что вместо этого приводит к чему-то вроде этого:

1111 1111 1111 1111 1111 1111 1001
person Jeach    schedule 07.11.2012
comment
Хорошим решением этой проблемы является создание битовой маски (в данном случае 0000 0000 0000 0000 0000 0000 1111) и &обработка результата с маской для принудительного удаления потенциальных расширенных ведущих единиц. - person mdhansen; 06.04.2016

Существует бесконечное количество возможных комбинаций. Однако они будут состоять из одной или нескольких комбинаций

>> shift right with sign extension.
>>> shift right with out sign extension.
<< shift left.

Чтобы понять, я предлагаю вам написать двоичные числа на бумаге и понять, что происходит. Попытка прочитать это в учебнике не гарантирует понимания. esp, если они не помогли до сих пор.

person Peter Lawrey    schedule 06.06.2011

Существует простой, но понятный учебник, который я считаю полезным здесь

person msb    schedule 06.06.2011
comment
Ссылка больше не работает. - person eddyrokr; 27.08.2014

Это не совсем учебник, но у меня есть личный библиотека функций побитового сдвига в Java, которую вы можете изучить!

Кроме того, если вы выполните поиск в Google по запросу "битовые трюки", вы найдете много материала. Многие из них написаны на C/C++, но, как правило, их легко преобразовать в Java, поскольку большая часть синтаксиса одинакова.

person mikera    schedule 06.06.2011


Этот сайт, кажется, дает довольно хороший учебник о том, что вы можете делать с битовыми манипуляциями (поэтому не относится к java, но поскольку его довольно легко перевести)

http://www.bogotobogo.com/cplusplus/quiz_bit_manipulation.html

Учебник выше обеспечивает

  • Побитовые операции
  • Установка и очистка бита
  • Отображение целого числа с битами
  • Преобразование десятичного числа в шестнадцатеричное
  • Количество битов, установленных в целом числе (количество единиц)
  • Битовая позиция целого числа
  • Целочисленный обмен на месте с битовыми манипуляциями
  • Количество битов, необходимых для преобразования целого числа A в целое число B
  • Поменять местами нечетные и четные биты в целом числе
  • Что (n & (n-1) == 0) проверяет?
  • Дополнение до двух
  • Переворачивание n-го бита целого числа
  • Битовая комбинация чисел с плавающей запятой
  • Палиндром битового шаблона целого числа

Вот файл с кучей реализаций Java

http://geekviewpoint.com/

person i8abug    schedule 28.09.2011

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

  1. Немного крутится
  2. Учебное пособие по PHP Bitwise от Джима Плюша
person mike    schedule 20.02.2012