wu :: forums
« wu :: forums - Ones in a register solution »

Welcome, Guest. Please Login or Register.
May 19th, 2024, 8:38am

RIDDLES SITE WRITE MATH! Home Home Help Help Search Search Members Members Login Login Register Register
   wu :: forums
   riddles
   cs
(Moderators: Icarus, Eigenray, towr, ThudnBlunder, Grimbal, william wu, SMQ)
   Ones in a register solution
« Previous topic | Next topic »
Pages: 1  Reply Reply Notify of replies Notify of replies Send Topic Send Topic Print Print
   Author  Topic: Ones in a register solution  (Read 2751 times)
Tom Shields
Guest

Email

Ones in a register solution  
« on: Jul 23rd, 2002, 10:07pm »
Quote Quote Modify Modify Remove Remove

int ones_in_an_int(int n)
{
  int count = 0;
  while (n) {
    count++;
    n = n & (n-1);
  }
  return count;
}
IP Logged
Marian Szczepkowski
Guest

Email

Re: Ones in a register solution  
« Reply #1 on: Jul 24th, 2002, 1:19am »
Quote Quote Modify Modify Remove Remove

Surely something like this
 
register r = 1;
int count;
for(count = 1; r > 0; count++) {
    r=r<<1;
}
return count;
 
Also works in assembler
1 mov a 0x01
2 mov b 0x01
3 incr b
4 rol a
5 jgt 3
 
 Grin
IP Logged
Tom Shields
Guest

Email

Re: Ones in a register solution  
« Reply #2 on: Jul 25th, 2002, 10:36pm »
Quote Quote Modify Modify Remove Remove

The problem states: "How can you determine the number of ones in an n-bit register only using i iterations, where i is the number of ones in the register?"
 
Your solution uses n iterations, not i iterations.  Also, there's a bug when there are no ones at all.
IP Logged
Tom Shields
Guest

Email

Re: Ones in a register solution  
« Reply #3 on: Jul 25th, 2002, 10:38pm »
Quote Quote Modify Modify Remove Remove

The bug in mine is: I should have used "unsigned" instead of "int".   Roll Eyes
IP Logged
S. Owen
Full Member
***





   


Gender: male
Posts: 221
Re: Ones in a register solution  
« Reply #4 on: Jul 27th, 2002, 11:49am »
Quote Quote Modify Modify

The solution comes from the observation that n & (n-1) always has one less bit on than n does (n is an unsigned value).
 
To show this, say that the lowest-order bit that is a 1 in a value n is at position k:
 n =   bits 1 0 0 ... 0
     k
The difference in bits between n and n-1 is only in bits k and lower:
 n-1 =   bits 0 1 1 ... 1
     k
So:
 n & (n-1) = bits 0 0 0 ... 0
     k
The & will result in the same higher-order bits, but k and lower are now all 0 - one less than n had.
 
So the algorithm is:
 
unsigned int n = ...;
if(n == 0) {
 return 0;
}
int count = 1;
while(n = (n & (n-1))) {
 count++;
}
return count;
 
 
The question that asks how to determine if a value is a power of two in a single statement is a special case of this.
IP Logged
cnmne
Guest

Email

Re: Ones in a register solution  
« Reply #5 on: Jul 28th, 2002, 7:01pm »
Quote Quote Modify Modify Remove Remove

this may not count, but it has no iterations...
 
int bit32on2( unsigned long a ) { // bitwise reduction tallying
 if ( a ) {
  register unsigned long  temp;
   
  a = ( a & ( temp = 0x55555555 ) ) + ( ( a >> 1 ) & temp );
  a = ( a & ( temp = 0x33333333 ) ) + ( ( a >> 2 ) & temp );
  a = ( a & ( temp = 0x07070707 ) ) + ( ( a >> 4 ) & temp );
  a = ( a & ( temp = 0x000F000F ) ) + ( ( a >> 8 ) & temp );
  a = ( a & ( temp = 0x0000001F ) ) + ( ( a >> 16 ) & temp );
 }
 return a;
}
IP Logged
Paul Hsieh
Guest

Email

Re: Ones in a register solution  
« Reply #6 on: Aug 6th, 2002, 11:06pm »
Quote Quote Modify Modify Remove Remove

Download the Athlon optimization guide:
 
http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/ 22007.pdf
 
The solution shown there (under "Population Count", page 136, and page 184) is probably the fastest way to do it in x86 processors, or in standard C.  (Other processors have popcount instructions, which would clearly be the fastest way for those platforms.)
 
The basic idea is to take 3 bits at a time, and translating them to the number of 1 bits among them in parallel using logical operations, then summing those partial results.
IP Logged
tseuG
Junior Member
**





   


Gender: male
Posts: 62
Re: Ones in a register solution  
« Reply #7 on: Jul 12th, 2004, 9:23am »
Quote Quote Modify Modify

   Extending the approach, if you had to do it a lot of times in software:
 
Prepare a 256 element array 'ones', in advance where ones[i] = number of 1's in the representation of i and where i ranges from 0 to 255.
 
Now, for each 32 bit number x,  
 
    unsigned char *cp = (unsigned char *) &x.
    return ones[*cp] + ones[*(cp+1)] + ones[*(cp+2)] + ones[*(cp+3)];
 
 
 
 
IP Logged
Pages: 1  Reply Reply Notify of replies Notify of replies Send Topic Send Topic Print Print

« Previous topic | Next topic »

Powered by YaBB 1 Gold - SP 1.4!
Forum software copyright © 2000-2004 Yet another Bulletin Board