Yep; you could go $count=substr_count(decbin($n),'1');, but that may be a bit heavy-handed, especially if it's something you're going to be it doing a lot for some reason.
So here are a few lines of bit-twiddling that will achieve the desired purpose. It assumes 32-bit integers:
$n = ($n&0x55555555) + (($n >> 1)&0x55555555);
$n = ($n&0x33333333) + (($n >> 2)&0x33333333);
$n = ($n&0x0f0f0f0f) + (($n >> 4)&0x0f0f0f0f);
$n = ($n&0x00ff00ff) + (($n >> 8)&0x00ff00ff);
$n = ($n&0x0000ffff) + (($n >>16)&0x0000ffff);
The first line replaces each successive pair of bits with the sum of those two bits (0+0=00, 0+1=01, 1+0=01, and 1+1=10, so the space occupied by those two bits is large enough to store the result: the addition can be done in-place); the second line takes each successive pair of these sums and adds them together - again, in place (the sum is never greater than 4, which can easily fit into four bits). The process repeats twice more. Each time, the sum of each pair of sums is small enough to fit in the space previously occupied by the pair (adding two n-bit numbers requires no more than n+1 bits of space to store the result and we have 2n bits available).
Let's got a little bit further - 'cos I'm in a didactic mood.
The above assumes that PHP has been built for a 32-bit platform. But there are 64-bit machines out there as well, and the above code will fail to count half the bits in a 64-bit integer. Now, while the sort of situations where you want to count bits are the sort where you know you're only going to be interested in the first 32 or so, a look at seeing how to support both architectures in one script in this instance might give ideas about how to cope with other situations.
First of all, we need to know how that code will look when written for a 64-bit machine. I leave that as an exercise for the reader (basically, the constants are twice as long, and there is a sixth line). Now that we have that, we need to be able to switch back and forth between them.
Now, we don't want to have to go around cutting-and-pasting blocks of code like that whenever we want to move between 32-bit and 64-bit machines. But we don't need to. We can set a constant and have it do the work of switching as appropriate:
define('INT64', true);
if(INT64)
{ include_once '64bitfunctions.php');
}
else
{ include_once '32bitfunctions.php');
}
But we'd still need to swap the value of INT64 back and forth between true and false ourselves.
No we don't. PHP can determine at compile/runtime whether it is running on a 64-bit or 32-bit machine and set the value of the constant accordingly. All we need is a bit of code that can be evaluated at that time that will tell us what we want to know.
It is a property of the two's-complement arithmetic notation which is pretty much universally used to represent binary integers that -1 is represented by a string of 1 bits. Ideally an infinitely long string, but on real computers they're generally restricted to the size of one CPU word - 32 bits on a 32-bit machine, 64 bits on a 64-bit machine.
So what we want to do is find out how many 1 bits our current machine uses to represent -1, and use that to determine whether INT64 should be true or false. Let's do that, then.
define('INT64', strlen(decbin(-1))==64);
if(INT64)
{ include_once '64bitfunctions.php');
}
else
{ include_once '32bitfunctions.php');
}
Yes, I know, I used decbin() after all. But instead of using it every time I want to count the number of bits in an integer (which would more likely than not be inside a loop), I only use it once, to determine how many bits I'll be needing to look at.
Edit: and now that the [font=monospace]PHP_INT_SIZE[/font] constant exists, that last decbin() call can go after all because we can just check the value of that. But are there that many 32-bit platforms still being used?