Пошаговое руководство
Давайте пройдемся по l oop с примером: давайте установим v = 42
, что составляет 0010 1010
в двоичном формате.
Первая итерация : c=0, v=42 (0010 1010)
. Теперь v-1
равно 41
, что является 0010 1001
в двоичном виде. Давайте вычислим v & v-1
:
0010 1010
& 0010 1001
.........
0010 1000
Теперь значение v&v-1
равно 0010 1000
в двоичном или 40 в десятичном виде. Это значение сохраняется в v
.
Вторая итерация : c=1, v=40 (0010 1000)
. Теперь v-1
равно 39
, что 0010 0111
в двоичном виде. Давайте вычислим v & v-1
:
0010 1000
& 0010 0111
.........
0010 0000
Теперь значение v&v-1
равно 0010 0000
, что составляет 32
в десятичном виде. Это значение сохраняется в v
.
Третья итерация : c=2, v=32 (0010 0000)
. Теперь v-1
равно 31
, что 0001 1111
в двоичном виде Давайте вычислим v & v-1
:
0010 0000
& 0001 1111
.........
0000 0000
Теперь значение v&v-1
равно 0
.
- Четвертая итерация :
c=3, v=0
. l oop завершается . c
содержит 3
, которое является числом битов, установленным в 42
.
Почему это работает
Вы можете видеть, что двоичное представление v-1
устанавливает младший значащий бит или младший бит (т. Е. Самый правый бит, равный 1) от 1 до 0, а все биты справа от младшего бита от 0 до 1.
Когда вы делаете поразрядно И между v
и v-1
, биты, оставшиеся от LSB, одинаковы в v
и v-1
, поэтому поразрядное И оставит их без изменений. Все биты справа от LSB (включая сам LSB) различны, поэтому результирующие биты будут равны 0.
В нашем первоначальном примере v=42 (0010 1010)
LSB - это второй бит справа. Вы можете видеть, что v-1
имеет те же биты, что и 42
, за исключением двух последних: 0 стал 1, а 1 стал 0.
Аналогично для v=40 (0010 1000)
младший бит является четвертым битом из право. При вычислении v-1 (0010 0111)
вы можете видеть, что левые четыре бита остаются неизменными, в то время как правые четыре бита стали инвертированными (нули стали единицами, а единицы стали нулями).
Следовательно, эффект v = v & v-1
заключается в установке наименьшего значения значительный бит от v
до 0 и оставьте остальные без изменений. Когда все биты очищены таким образом, v
равно 0, и мы посчитали все биты.