количество заданных битов в целых числах - PullRequest
0 голосов
/ 22 марта 2012

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

pop(x)=-sum(x<<i)   where i=0:31

Я думаю, что после вычисления каждого значениях, мы получим

x+2*x+4*x+8*x+16*x+..............+2^31*x  =4294967294*x

, если мы умножим его на -1, мы получим -4294967294*x, но как он подсчитывает количество бит? Пожалуйста, помогите мне хорошо понять этот метод. Спасибо

Ответы [ 2 ]

5 голосов
/ 22 марта 2012

Я полагаю, вы имеете в виду

$$\mathrm{pop}(x) = -\sum_{i=0}^{31} (x \overset{\mathrm{rot}}{\ll} i)$$

, как видно на обложке книги Восторг Хакера , где символ означает слева- вращение не влево- смещение , что приведет к неправильным результатам и отрицательным голосам.

Этот метод работает, поскольку вращение вызовет все двоичные цифры x , чтобы появиться во всех возможных битах во всех терминах, и из-за дополнения 2.

Возьмите более простой пример.Рассмотрим числа только с 4 двоичными цифрами, где цифры могут быть представлены как ABCD, тогда суммирование означает:

  ABCD  // x <<rot 0
+ BCDA  // x <<rot 1
+ CDAB  // x <<rot 2
+ DABC  // x <<rot 3

Заметим, что в каждом столбце есть все A, B, C, D. Теперь, ABCD фактически означает «2³ A + 2² B + 2¹ C + 2⁰ D», поэтому сумма равна:

  2³ A        + 2² B        + 2¹ C        + 2⁰ D
+ 2³ B        + 2² C        + 2¹ D        + 2⁰ A
+ 2³ C        + 2² D        + 2¹ A        + 2⁰ B
+ 2³ D        + 2² A        + 2¹ B        + 2⁰ C
——————————————————————————————————————————————————————
= 2³(A+B+C+D) + 2²(B+C+D+A) + 2¹(C+D+A+B) + 2⁰(D+A+B+C)
= (2³ + 2² + 2¹ + 2⁰) × (A + B + C + D)

(A + B + C + D) - это число населения x и (2³ + 2² + 2¹ + 2⁰) = 0b1111 равно -1 в дополнении к 2, поэтому суммирование является отрицательным числом подсчета населения.

Аргумент может быть легко расширен до32-разрядные числа.

0 голосов
/ 19 декабря 2014
#include <stdio.h>
#include <conio.h>

unsigned int f (unsigned int a , unsigned int b);

unsigned int f (unsigned int a , unsigned int b)
{
   return a ?   f ( (a&b) << 1, a ^b) : b;
}

int bitcount(int n) {
    int tot = 0;

    int i;
    for (i = 1; i <= n; i = i<<1)
        if (n & i)
            ++tot;

    return tot;
}

int bitcount_sparse_ones(int n) {
    int tot = 0;

    while (n) {
        ++tot;
        n &= n - 1;
    }

    return tot;
}

int main()
{

int a = 12;
int b = 18;

int c = f(a,b);
printf("Sum = %d\n", c);

int  CountA = bitcount(a);
int  CountB = bitcount(b);

int CntA = bitcount_sparse_ones(a);
int CntB = bitcount_sparse_ones(b);

printf("CountA = %d and CountB = %d\n", CountA, CountB);
printf("CntA = %d and CntB = %d\n", CntA, CntB);
getch();

return 0;

}
...