C++ 按位和

C++ 按位和,c++,c,bitwise-and,C++,C,Bitwise And,这个问题是在一次采访中提出的,有人能告诉我下面的代码是做什么的吗?它给出了150的输出15,160的输出3,15的输出15。它对“n”执行什么数学运算 int foo(int n) { int t,count=0; t=n; while(n) { count=count+1; n=(n-1)&t; } return count; } 它似乎在计算数字max(n**2-1,0),其中n是数字二进制表示中1位

这个问题是在一次采访中提出的,有人能告诉我下面的代码是做什么的吗?它给出了150的输出15,160的输出3,15的输出15。它对“n”执行什么数学运算

int foo(int n) 
{
    int t,count=0;
    t=n;
    while(n)
    {
        count=count+1;
        n=(n-1)&t;
    }
    return count;
}

它似乎在计算数字
max(n**2-1,0)
,其中n是数字二进制表示中
1
位的数量:

    0     0 0b0  
    1     1 0b1  
    2     1 0b10 
    3     3 0b11 
    4     1 0b100
    5     3 0b101
    6     3 0b110
    7     7 0b111
    8     1 0b1000
    9     3 0b1001
   10     3 0b1010
   11     7 0b1011
   12     3 0b1100
   13     7 0b1101
   14     7 0b1110
   15    15 0b1111
   16     1 0b10000
   17     3 0b10001
   18     3 0b10010
   19     7 0b10011
   20     3 0b10100
   21     7 0b10101
   22     7 0b10110
   23    15 0b10111
   24     3 0b11000
   25     7 0b11001
   26     7 0b11010
   27    15 0b11011
   28     7 0b11100
   29    15 0b11101
   30    15 0b11110
   31    31 0b11111
   32     1 0b100000
   33     3 0b100001
   34     3 0b100010
   35     7 0b100011
   36     3 0b100100
   37     7 0b100101
   38     7 0b100110
   39    15 0b100111
   40     3 0b101000
   41     7 0b101001
   42     7 0b101010
   43    15 0b101011
   44     7 0b101100
   45    15 0b101101
   46    15 0b101110
   47    31 0b101111
   48     3 0b110000
   49     7 0b110001
   50     7 0b110010
   51    15 0b110011
   52     7 0b110100
   53    15 0b110101
   54    15 0b110110
   55    31 0b110111
   56     7 0b111000
   57    15 0b111001
   58    15 0b111010
   59    31 0b111011
   60    15 0b111100
   61    31 0b111101
   62    31 0b111110
   63    63 0b111111
   64     1 0b1000000
   65     3 0b1000001
   66     3 0b1000010
   67     7 0b1000011
   68     3 0b1000100
   69     7 0b1000101
   70     7 0b1000110
   71    15 0b1000111
   72     3 0b1001000
   73     7 0b1001001
   74     7 0b1001010
   75    15 0b1001011
   76     7 0b1001100
   77    15 0b1001101
   78    15 0b1001110
   79    31 0b1001111
   80     3 0b1010000
   81     7 0b1010001
   82     7 0b1010010
   83    15 0b1010011
   84     7 0b1010100
   85    15 0b1010101
   86    15 0b1010110
   87    31 0b1010111
   88     7 0b1011000
   89    15 0b1011001
   90    15 0b1011010
   91    31 0b1011011
   92    15 0b1011100
   93    31 0b1011101
   94    31 0b1011110
   95    63 0b1011111
   96     3 0b1100000
   97     7 0b1100001
   98     7 0b1100010
   99    15 0b1100011

当函数更改为递归时,更容易找到“数学运算”:

int foo(int n, int t) 
{
    if( n )
        return foo( (n-1) & t ) + 1
    else
        return 0; 
}
所以公式是:

F(0,t) = 0
F(n,t) = F( (n-1) & t, t ) + 1

foo(n) = F(n,n)
我不知道,这是不是一个众所周知的计算公式

您可以从以下方法中找到答案:

Brian Kernighan的方法经过的迭代次数与设置的比特数一样多。因此,如果我们有一个32位的字,只有高位集,那么它将只经过一次循环

1988年出版的C编程语言第二版(Brian W.Kernighan和Dennis M.Ritchie)在练习2-9中提到了这一点。2006年4月19日,唐·克努特(Don Knuth)向我指出,这种方法“由彼得·韦格纳(Peter Wegner)在CACM 3(1960),322中首次发表。(德里克·莱默(Derrick Lehmer)也独立发现,并于1964年在贝肯巴赫编辑的一本书中发表。)


你为什么不编译它,运行它,然后找出答案呢?@OliCharlesworth我这样做了,输入150它给出15,输入160它给出3。我想问它对“n”做了什么数学运算。好吧,但你的问题本质上是“这个任意位的未记录代码做了什么?”,这不太适合堆栈溢出。按位运算符的行为可以在Wikipedia()上找到。我知道按位运算符的功能,但在lcm或hcf或其他方面计算的功能是否相同
unsigned int v; // count the number of bits set in v
unsigned int c; // c accumulates the total bits set in v
for (c = 0; v; c++)
{
  v &= v - 1; // clear the least significant bit set
}