Подтвердить что ты не робот

О каких ПОЛЕЗНЫХ ПОСЛЕДОВАТЕЛЬНЫХ ПОДАВЛЕНИЯХ кода оператора должен знать разработчик?

Я должен сказать, что у меня никогда не было причины использовать побитовые операторы, но я уверен, что некоторые операции, которые я выполнил, были бы более эффективно с ними. Как "переключение" и "OR-ing" помогли вам решить проблему более эффективно?

4b9b3361

Ответ 1

Посмотрите знаменитый Бит Twiddling Hacks
Большинство размножающихся/делящих не нужны - компилятор сделает это автоматически, и вы просто смутите людей.

Но есть множество типов "check/set/toggle bit N", которые очень полезны, если вы работаете с аппаратными или коммуникационными протоколами.

Ответ 2

Использование побитовых операций над строками (символами)

Преобразовать письмо в в нижнем регистре:

  • OR по пространству = > (x | ' ')
  • Результат всегда строчный, даже если буква уже имеет строчные буквы
  • например. ('a' | ' ') => 'a'; ('a' | ' ') => 'a'

Преобразовать письмо в в верхнем регистре:

  • AND by underline = > (x & '_')
  • Результат всегда в верхнем регистре, даже если буква уже прописная.
  • например. ('a' & '_') => 'A'; ('a' & '_') => 'A'

Инвертировать регистр букв:

  • XOR по пространству = > (x ^ ' ')
  • например. ('a' ^ ' ') => 'A'; ('a' ^ ' ') => 'A'

Буква позиция в алфавите:

  • AND chr(31)/binary('11111')/(hex('1F') = > (x & "\x1F")
  • Результат в диапазоне 1..26, регистр букв не важен
  • например. ('a' & "\x1F") => 1; ('B' & "\x1F") => 2

Получить букву position в алфавите (только для букв Только для верхнего):

  • AND на ? = > (x & '?') или XOR на @ = > (x ^ '@')
  • например. ('C' & '?') => 3; ('Z' ^ '@') => 26

Получить букву позицию в алфавите (только для строчных):

  • XOR с помощью обратного хода / chr(96)/binary('1100000')/hex('60') = > (x ^ '`')
  • например. ('d' ^ '`') => 4; ('x' ^ '`') => 25

Примечание: использование чего-либо, кроме английских букв, приведет к результатам мусора

Ответ 3


  • Побитовые операции с целыми числами (int)

Получить максимальное целое число

int maxInt = ~(1 << 31);
int maxInt = (1 << 31) - 1;
int maxInt = (1 << -1) - 1;

Получить минимальное целое число

int minInt = 1 << 31;
int minInt = 1 << -1;

Получить максимальную длину

long maxLong = ((long)1 << 127) - 1;

Умножается на 2

n << 1; // n*2

Разделено на 2

n >> 1; // n/2

Умножается на m-ю степень 2

n << m;

Разделенная на m-ю степень 2

n >> m;

Проверить нечетное число

(n & 1) == 1;

Обмен двумя значениями

a ^= b;
b ^= a;
a ^= b;

Получить абсолютное значение

(n ^ (n >> 31)) - (n >> 31);

Получить максимум двух значений

b & ((a-b) >> 31) | a & (~(a-b) >> 31);

Получить минимум двух значений

a & ((a-b) >> 31) | b & (~(a-b) >> 31);

Проверьте, имеют ли обе тот же знак

(x ^ y) >= 0;

Вычислить 2 ^ n

2 << (n-1);

Является ли факториал 2

n > 0 ? (n & (n - 1)) == 0 : false;

Modulo 2 ^ n против m

m & (n - 1);

Получить средний

(x + y) >> 1;
((x ^ y) >> 1) + (x & y);

Получить m-й бит n (от низкого до высокого)

(n >> (m-1)) & 1;

Установите m-й бит n в 0 (от низкого до высокого)

n & ~(1 << (m-1));

n + 1

-~n

n - 1

~-n

Получить контрастность

~n + 1;
(n ^ -1) + 1; 

, если (x == a) x = b; if (x == b) x = a;

x = a ^ b ^ x;

Ответ 4

Там только три, которые я когда-либо использовал с любой частотой:

  • Установите бит: a | = 1 < бит;

  • Очистить бит: a & = ~ (1 < бит);

  • Проверьте, что бит установлен: a и (1 < бит);

Ответ 5

Вопросы вычислительные: идеи, алгоритмы, исходный код, Йорг Арндт (PDF). Эта книга содержит множество вещей, я нашел ее по ссылке http://www.hackersdelight.org/

Среднее значение без переполнения

Процедура вычисления среднего (x + y)/2 двух аргументы x и y

static inline ulong average(ulong x, ulong y)
// Return floor( (x+y)/2 )
// Use: x+y == ((x&y)<<1) + (x^y)
// that is: sum == carries + sum_without_carries
{
    return (x & y) + ((x ^ y) >> 1);
}

Ответ 6

Вы можете сжимать данные, например. набор целых чисел:

Ответ 7

Подсчет бит бит, поиск минимального/наивысшего бита набора, поиск бит nth-from-top/bottom и других может быть полезным, и стоит посмотреть бит-twiddling hacks.

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

Ответ 8

1) Разделить/Умножить на мощность 2

foo >>= x; (разделите по мощности 2)

foo <<= x; (умножить на мощность 2)

2) Swap

x ^= y;
y = x ^ y;
x ^= y;

Ответ 9

В то время как умножение/деление на сдвиг кажется отличным, единственное, что мне нужно было время от времени - сжимать булевы в биты. Для этого вам нужно поразрядное AND/OR и, возможно, смещение/инвертирование битов.

Ответ 10

Мне нужна функция для округления чисел до следующей максимальной мощности в два, поэтому я посетил сайт Bit Twiddling, который несколько раз поднимался и придумывал следующее:

i--;
i |= i >> 1;
i |= i >> 2;
i |= i >> 4;
i |= i >> 8;
i |= i >> 16;
i++;

Я использую его по типу size_t. Вероятно, он не будет хорошо воспроизводить подписанные типы. Если вы беспокоитесь о переносимости платформ с различными размерами, покройте свой код директивами #if SIZE_MAX >= (number) в соответствующих местах.

Ответ 11

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