13

Possible Duplicate:
Best algorithm to count the number of set bits in a 32-bit integer?

I want to find out how many 1s are there in binary representation of a number.I have 2 logic .

  1.   int count =0;
    int no = 4;
    
    while(no!=0){
        int d = no%2;
        if(d==1)
            count++;
        no = no/2;
        str = str+ d;
    }
    
  2. Now second logic is to keep on masking number iteratively with 1,2,4,8,32 and check if result is 1,2,4, 8..... Am not geting what should be ending condition for this loop.

Community
  • 1
  • 1
akshayxyz
  • 3,423
  • 3
  • 16
  • 11

8 Answers8

35

Use Java API(java 5 or above).

Integer.bitCount(int);
Long.bitCount(long);

NOTE: The above java methods are based on hacker's delight

Prince John Wesley
  • 62,492
  • 12
  • 87
  • 94
16

faster than any of the earlier answers: (proportional to number of 1 bits rather than total bits)

public class Foo {
  public static void main(String[] argv) throws Exception {
    int no = 12345;
    int count;
    for (count = 0; no > 0; ++count) {
      no &= no - 1;
    }
    System.out.println(count);
  }
}
necromancer
  • 23,916
  • 22
  • 68
  • 115
  • and doesn't require you to know how many bits to iterate over, etc. =) – necromancer Mar 11 '11 at 01:23
  • No as it can be optimized away to 0 ! ;) but if you fix the error, its very much unlikely it will perform better anyways (ducks) – stefan Mar 11 '11 at 01:30
  • stefan: Whenever `no` is a constant the loop can be optimized away. – Gabe Mar 11 '11 at 01:39
  • @stefan -- funny about optimizing away the 0, but if you change no to be a parameter it will definitely perform better because it runs proportional to number of 1 bits, rather than proportional to number of bits like the other solutions. in other words, if no = 1024, the loop will run exactly once -- makes sense? – necromancer Mar 11 '11 at 07:55
3

Looks like c/c++/c#, if so you have shifting.. just loop to N-1 bits from 0 and use sum+=(value>>i)&1

Ie: you always check the last/right most bit but move the binary representation of the number to the right for every iteration until you have no more bits to check.

Also, think about signed/unsigned and any integer format. But you dont state how that should be handled in the question.

stefan
  • 2,886
  • 21
  • 27
2

We can make use of overflow for your loop:

int count = 0;
int number = 37;
int mask = 1;

while(mask!=0)
{
    int d = number & mask;
    if(d != 0)
        count++;
    /* Double mask until we overflow, which will result in mask = 0... */
    mask = mask << 1;
    str = str+ d;
}
Heath Hunnicutt
  • 18,667
  • 3
  • 39
  • 62
  • 3
    @akshayxyz If you don't know, then I think you fail the interview :) – Phrogz Mar 11 '11 at 01:18
  • 1
    @Phrogz: I don't know what language it is either. If it were C++ or Java, it wouldn't have an `OverflowException`. If it were C#, it would require a `checked` block to get the exception. – Gabe Mar 11 '11 at 01:29
  • Sorry about the OverflowException, I crossed my Java and my C#. The above revision should work fine in Java. – Heath Hunnicutt Mar 11 '11 at 01:58
2

One idea that's commonly employed for counting ones is to build a lookup table containing the answers for each individual byte, then to split apart your number into four bytes and sum the totals up. This requires four lookups and is quite fast. You can build this table by writing a program that manually computes the answer (perhaps using your above program), and then can write a function like this:

private static final int[] BYTE_TOTALS = /* ... generate this ... */;

public static int countOneBits(int value) {
    return BYTE_TOTALS[value        & 0xFF] +
           BYTE_TOTALS[value >>>  8 & 0xFF] +
           BYTE_TOTALS[value >>> 16 & 0xFF] +
           BYTE_TOTALS[value >>> 24 & 0xFF];
}

Hope this helps!

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
1

There are various ways to do this very fast.

MIT HAKMEM Count

int no =1234;
int tmp =0;
tmp = no - ((no >> 1) & 033333333333) - ((no >> 2) & 011111111111);
System.out.println( ((tmp + (tmp >> 3)) & 030707070707) % 63);
Dead Programmer
  • 12,427
  • 23
  • 80
  • 112
0

Your end condition should be keeping track of the magnitude of the bit you are at; if it is larger than the original number you are done (will get only 0s from now on).

Oh, and since you didn't specify a language, here's a Ruby solution :)

class Integer
  def count_binary_ones
    to_s(2).scan('1').length
  end
end

42.count_binary_ones #=> 3
Phrogz
  • 296,393
  • 112
  • 651
  • 745
  • sorry i dont understand ruby code – akshayxyz Mar 11 '11 at 01:07
  • But one might be able appreciate it - except for the monkey patching ;) – miku Mar 11 '11 at 01:29
  • The `int` in the code sample should have tipped you off that he's using signed integers, meaning that the magnitude check wouldn't work. Also, it should have told you that Ruby code isn't useful. – Gabe Mar 11 '11 at 01:43
0

How about using the BigInteger class.

public void function(int checkedNumber) {
    BigInteger val = new BigInteger(String.valueOf(checkedNumber));
    val = val.abs();
    int count = val.bitCount();
    String binaryString = val.toString(2);

    System.out.println("count = " + count);
    System.out.println("bin = " + binaryString);
}

The result of function(42); is following.

count = 3
bin = 101010
Yu Sun corn
  • 616
  • 6
  • 8