Почему (x & 3) идентично (x mod 4)? - PullRequest
4 голосов
/ 24 октября 2011

Я нашел пример исходного кода, где автор, кажется, использует битовый оператор & вместо оператора %.Однако, когда я попробовал x & 4, он не выдает то же значение, что и x % 5.

Ответы [ 2 ]

16 голосов
/ 24 октября 2011

Это работает только для степеней 2.

В целом:

x MOD 2^n

эквивалентно:

x AND (2^n - 1)

Обратите внимание, что это может быть только правдойдля x >= 0, в зависимости от вашего определения MOD для x < 0.


Чтобы понять , почему это работает, подумайте, что такое MOD на самом деле - это просто остаток после выполнения целочисленного деления.В случае деления на 2 ^ n мы фактически просто сдвигаем двоичное значение вправо на n битов и отбрасываем любые биты младшего разряда, которые сдвинуты, например, для 8-битного двоичного числа

a b c d e f g h

если мы разделим на 4 = 2 ^ 2, то мы сдвинемся вправо на 2 бита:

0 0 a b c d e f

Остаток (g h) был отброшен в результате целочисленного деления.

Если бы мы хотели знать остаток, то мы могли бы просто извлечь биты g h, применив маску 0 0 0 0 0 0 1 1:

    a b c d e f g h
AND 0 0 0 0 0 0 1 1
  = 0 0 0 0 0 0 g h

Обратите внимание, что имеет значение 3, которое в общем случае равнопросто 2 ^ n - 1.

Давайте попробуем это с некоторыми действительными числами.Предположим, мы хотим вычислить 42/4 и получить как частное, так и остаток:

42 = 0 0 1 0 1 0 1 0

Чтобы получить частное, мы сдвигаемся вправо на 2 бита:

  42 / 4 (decimal)
= 0 0 1 0 1 0 1 0 >> 2
= 0 0 0 0 1 0 1 0
= 10 (decimal)

  42 MOD 4 (decimal)
= 0 0 1 0 1 0 1 0 AND 0 0 0 0 0 0 1 1
= 0 0 0 0 0 0 1 0
= 2 (decimal)

Итак, 42/4= 10 остаток 2.

4 голосов
/ 24 октября 2011

Ответ довольно прост, попробуйте думать в двоичном виде.

0000 = 0 AND 11 = 0000 = 0
0001 = 1 AND 11 = 0001 = 1
0010 = 2 AND 11 = 0010 = 2
0011 = 3 AND 11 = 0011 = 3
0100 = 4 AND 11 = 0000 = 0
0101 = 5 AND 11 = 0001 = 1
0110 = 6 AND 11 = 0010 = 2
0111 = 7 AND 11 = 0011 = 3

... и т. Д.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...