Битовые операции
Число как набор битов: маски, сдвиги и почему сдвиг на 64 ничего не меняет
Любое целое число — это набор битов: 12 — это 1100, 10 — это 1010. Шесть операций op
работают не с числом целиком, а с каждым битом по отдельности.
Это нужно нечасто, но когда нужно — заменить нечем: несколько признаков в одном числе, проверка «включён ли такой-то бит», быстрое умножение на степень двойки.
| Операция | В блоке | Что делает | 12 и 10 |
|---|---|---|---|
and |
b-and |
бит остаётся, если он есть в обоих | 8 (1000) |
or |
or |
бит остаётся, если он есть хоть в одном | 14 (1110) |
xor |
xor |
бит остаётся, если он есть ровно в одном | 6 (0110) |
not |
flip |
все биты наоборот | −6 из 5 |
shl |
<< |
сдвиг влево: умножение на 2 столько раз | 8 из 1 и 3 |
shr |
>> |
сдвиг вправо: деление на 2 столько раз | 1 из 8 и 3 |
Столбец «В блоке» стоит прочесть внимательно: побитовое «и» подписано b-and, потому что
and в списке уже занято логическим «и», а побитовая инверсия — flip, потому что not
занято сравнением «не равно». Имена в справочниках и знаки на кнопках здесь расходятся
сильнее всего.
Сдвиг — самый понятный из шести: shl 1 3 двигает единственный бит на три позиции влево
и превращает 1 в 8. Обратный shr возвращает 8 в 1.
Всё считается в целых, и целых длинных
Заголовок раздела «Всё считается в целых, и целых длинных»Перед битовой операцией число приводится к целому: дробная часть отбрасывается,
and от 12.7 и 10 даст те же 8, что и от 12.
Целое при этом длинное, 64-битное, и знаковое — от −2⁶³ до 2⁶³−1.
Три ответа, которых никто не ждёт
Заголовок раздела «Три ответа, которых никто не ждёт»shl 1 64 даёт 1, а не ноль. У сдвига берутся только младшие шесть битов второго числа,
то есть остаток от деления на 64. Сдвиг на 64 — это сдвиг на 0, сдвиг на 65 — на 1.
Ноль не получится никак.
shr −8 1 даёт −4, а не большое число. shr знаковый: он двигает биты вправо, а слева
дописывает знак, поэтому отрицательное остаётся отрицательным. Деление пополам работает
и для минусов.
ushr −1 60 даёт 15. А вот ushr знак не бережёт: он считает число беззнаковым,
и −1 для него — это 64 единичных бита. Сдвинули на 60, осталось четыре: 15.
Зачем это в игре
Заголовок раздела «Зачем это в игре»Главный случай — уместить несколько чисел в одно. Переменных у процессора много,
а мест, куда можно положить число для другого процессора, мало: ячейка памяти, флаг юнита.
Сдвигами и or в одно число складывают несколько, а shr и and достают обратно.
Сколько чисел туда влезет, решает тот самый предел: на всё про всё 53 бита. Разбор — в уроке «Число внутри».
Неофициальный проект, с Anuke не связан. Спрайты, шрифты и переводы Mindustry © Anuke, используются по GPL-3.0; Fira Code — по OFL-1.1. Код сайта — GPL-3.0.