I have an array of integers (let us assume here 32 bit ints).
N=SomeValue; int *ptr=new int[N];
Does there exist some clever way to sum all the ones (positive bits) instead of going trough every bit and converting it to bool, and if true then sum++?
Posted 05 October 2012 - 01:04 AM
N=SomeValue; int *ptr=new int[N];
Posted 05 October 2012 - 01:42 AM
Posted 05 October 2012 - 04:40 AM
// initialize table, could be constant, but that's a lot to type out
int numBits[256] = { };
for(int i = 0; i < 256; ++i) {
numBits[i] =
((i & 0x01) ? 1 : 0) +
((i & 0x02) ? 1 : 0) +
((i & 0x04) ? 1 : 0) +
((i & 0x08) ? 1 : 0) +
((i & 0xF0) ? 1 : 0) +
((i & 0xF1) ? 1 : 0) +
((i & 0xF2) ? 1 : 0) +
((i & 0xF4) ? 1 : 0) +
((i & 0xF8) ? 1 : 0);
}
int *ptr=new int[N];
int totalNumBits;
for(int i = 0; i < N; ++i) {
union {
int integer;
char charArray[4];
} int2char;
int2char.integer = ptr[i];
totalNumBits += numBits[int2char.charArray[0]] + numBits[int2char.charArray[1]] + numBits[int2char.charArray[2]] + numBits[int2char.charArray[3]];
}
Posted 05 October 2012 - 05:05 AM
http://www.cpgf.org/
cpgf library -- free C++ open source library for reflection, serialization, script binding, callbacks, and meta data for OpenGL Box2D, SFML and Irrlicht.
v1.5.5 was released. Now supports tween and timeline for ease animation.
Posted 05 October 2012 - 07:58 AM
unsigned popcount(unsigned x) {
x -= (x >> 1) & 0x55555555u;
x = (x & 0x33333333u) + ((x >> 2) & 0x33333333u);
x = (x + (x >> 4)) & 0x0f0f0f0fu;
return (x * 0x01010101u) >> 24; // assumes unsigned is 32 bits
}
Edited by alvaro, 05 October 2012 - 08:26 AM.
Posted 05 October 2012 - 08:51 AM
Talking about performance, here is my personal experience (maybe off topic).gcc also has a function called __builtin_popcount, but on my computer the one above is three times faster. You can do it even faster using 64-bit arithmetic.
Edited by wqking, 05 October 2012 - 08:54 AM.
http://www.cpgf.org/
cpgf library -- free C++ open source library for reflection, serialization, script binding, callbacks, and meta data for OpenGL Box2D, SFML and Irrlicht.
v1.5.5 was released. Now supports tween and timeline for ease animation.
Posted 05 October 2012 - 12:10 PM
That function scares me...This code (or similar) is somewhere in that bithacks page wqking linked:
unsigned popcount(unsigned x) { x -= (x >> 1) & 0x55555555u; x = (x & 0x33333333u) + ((x >> 2) & 0x33333333u); x = (x + (x >> 4)) & 0x0f0f0f0fu; return (x * 0x01010101u) >> 24; // assumes unsigned is 32 bits }
Posted 05 October 2012 - 12:24 PM
That function scares me...
This code (or similar) is somewhere in that bithacks page wqking linked:unsigned popcount(unsigned x) { x -= (x >> 1) & 0x55555555u; x = (x & 0x33333333u) + ((x >> 2) & 0x33333333u); x = (x + (x >> 4)) & 0x0f0f0f0fu; return (x * 0x01010101u) >> 24; // assumes unsigned is 32 bits }
x -= (x >> 1) & 0x55555555u; // 0x55555555u is 01010101010101010101010101010101 in binary
x = (x & 0x33333333u) + ((x >> 2) & 0x33333333u); x = (x + (x >> 4)) & 0x0f0f0f0fu;
ABCD x 1111 ------ ABCD ABCD ABCD ABCD ------- abcdefgNotice that there is no carry in this sum, because all the digits A, B, C and D are at most 8. Since we are doing this whole thing in 32-bit arithmetic, abc is lost to overflow, and the result of the multiplication is really just defg. As you see d=A+B+C+D, and we can extract it with a shift 24 bits to the right.
return (x * 0x01010101u) >> 24; // assumes unsigned is 32 bits
Edited by alvaro, 05 October 2012 - 12:25 PM.
Posted 05 October 2012 - 01:01 PM
Written in Notepad, it may or may not compile.
Also it's not tested, it may or may not be faster/slower, that's up to you to test.
It's also incorrect, you would need to test against:
0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80.