-3

This question was asked in an interview, can someone tell what does the following code do? It gives output 15 for 150, 3 for 160, 15 for 15. What mathematical operation is it performing on 'n'.

int foo(int n) 
{
    int t,count=0;
    t=n;
    while(n)
    {
        count=count+1;
        n=(n-1)&t;
    }
    return count;
}
Arunkumar Chandrasekaran
  • 1,211
  • 4
  • 21
  • 40
Vanya
  • 361
  • 5
  • 16
  • 3
    Why don't you compile it, run it, and find out? – Oliver Charlesworth Jul 15 '12 at 17:29
  • @OliCharlesworth I did that, for input 150 it gives 15 and for 160 its 3. I wanted to ask what mathematical operation is it doing on 'n'. – Vanya Jul 15 '12 at 17:33
  • 2
    Ok, but your question is essentially "what does this arbitrary bit of undocumented code do?", which is not really suitable for Stack Overflow. The behaviour of bitwise operators can be found at e.g. Wikipedia (http://en.wikipedia.org/wiki/Bitwise_operators). – Oliver Charlesworth Jul 15 '12 at 17:34
  • I know the functioning of bitwise operators, but was is the function computing as in lcm or hcf or something else – Vanya Jul 15 '12 at 17:39

3 Answers3

1

It seems to calculate the number max(n**2-1, 0), where n is the number of 1 bits in a number's binary representation:

    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
Ilmo Euro
  • 4,925
  • 1
  • 27
  • 29
0

It is easier to find out the "mathematical operation", when function is changed to recursive:

int foo(int n, int t) 
{
    if( n )
        return foo( (n-1) & t ) + 1
    else
        return 0; 
}

So formula is:

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

foo(n) = F(n,n)

I don't have any idea, is that wellknown formula for counting something, or not.

You may find answer from math.stackexchange.com

SKi
  • 8,007
  • 2
  • 26
  • 57
0

That is a method known as Brian Kernighan's way to count set bits :

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
}

Brian Kernighan's method goes through as many iterations as there are set bits. So if we have a 32-bit word with only the high bit set, then it will only go once through the loop.

Published in 1988, the C Programming Language 2nd Ed. (by Brian W. Kernighan and Dennis M. Ritchie) mentions this in exercise 2-9. On April 19, 2006 Don Knuth pointed out to me that this method "was first published by Peter Wegner in CACM 3 (1960), 322. (Also discovered independently by Derrick Lehmer and published in 1964 in a book edited by Beckenbach.)"

BЈовић
  • 62,405
  • 41
  • 173
  • 273