We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › rounding up bitwise
Page Index Toggle Pages: 1
rounding up bitwise (Read 1771 times)
rounding up bitwise
Aug 18th, 2006, 2:07pm
 
Anyone know how to round up to the nearest power of 2?

I've got two binary numbers I want to cross over:
Code:

int x = unbinary("1001110101110");
int m = unbinary("0000000011111");
int y = unbinary("1100100010101");
println(binary(x^((x^y)&m)));

The mask "m" selects the section from y to cross over. But I want that mask to be of an arbitrary size. Which I can do with the following:
Code:

int m = (1<<sizeOfMask)-1;
// A sizeOfMask set to 3 would create the binary:
// 111

But say I'm going to be dealing with binary numbers up to 14 (1110). I know myself that I'm only going to mask up to 4 bits. But I want to create a class which can figure that out for itself.

The way to do that would be to round up to the nearest power of 2. Which for 14 would be sixteen (10000). Then I would know how many bits I've got to play with.

I'm trying to find a way which is a bit more elegant than:
Code:

int bits = 0;
while(num > 0){
num >>=1;
bits++;
}


This is in aid of making a memory compact genetic algorithm. By masking and XORing I can perform the crossover and mutation of traits without translating into a StringBuffer a binary representation. (Mutation would be simply a power of two that I XOR the target by). Without knowing the range of bits I can crossover and mutate in though I won't be able to keep the new genetic traits in an acceptable number range.
Re: rounding up bitwise
Reply #1 - Aug 18th, 2006, 2:41pm
 
I needed the same for forcing the window size of an FFT to be powers-of-2...

Code:

int VALUE = 14;
int BIT_LEN = round(log(VALUE)/log(2)+0.5);


That should do it!
Re: rounding up bitwise
Reply #2 - Aug 18th, 2006, 4:21pm
 
That's cool and thankyou but it's also really bloody slow.

I found this great page (where I got the masking hack from):

http://graphics.stanford.edu/~seander/bithacks.html

Your reply tipped me off that I was trying to find log base 2, so I figured out what it was I was looking for on the bit hacks page. The following example is nearly ten times faster (tested) that the float method.

It was the only trick there that I could easily translate into Java. If anyone knows how to translate the quicker ones I'd be really grateful. (This one looked faster with only 7 operations, but I will stick to this one for now if no one feels like tackling it).
Code:

static final int [] MultiplyDeBruijnBitPosition = {
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
int timer;

void setup(){
int b = unbinary("0000100100000");
int q = 0;
timer = millis();
for(int i = 0; i < 1000000; i++){
q = bitLog1(b);
}
println(millis() - timer);
q = 0;
timer = millis();
for(int i = 0; i < 1000000; i++){
q = bitLog2(b);
}
println(millis() - timer);

}
int bitLog1(int num){
num |= num >> 1; // first round down to power of 2
num |= num >> 2;
num |= num >> 4;
num |= num >> 8;
num |= num >> 16;
num = (num >> 1) + 1;
return MultiplyDeBruijnBitPosition[(num * 0x077CB531) >> 27];
}
int bitLog2(int num){
return round(log(num)/log(2));
}
Re: rounding up bitwise
Reply #3 - Aug 18th, 2006, 7:54pm
 
Good news! Getting rid of the StringBuffer in a Genetic Algorithm is 150% faster. Bitwise integers is the way forward. Just need to go through it with a fine tooth comb though to make sure it's properly debugged.
Re: rounding up bitwise
Reply #4 - May 6th, 2009, 2:38pm
 
My apologies toxi.

Wouldn't you believe it, the above algorithm I mentioned only works up to 5 bits. Feed it a number higher than 32 and it crashes. I've been wondering why the GA I wrote seems to choke at trait sizes larger than 32. I'm gonna switch to the the slow method.

*shakes fist at Bit Twiddling Hacks
Re: rounding up bitwise
Reply #5 - May 6th, 2009, 4:08pm
 
Using BigInteger would give you lots more bits (as many as you have memory for).

http://java.sun.com/j2se/1.4.2/docs/api/java/math/BigInteger.html

Or you could use an array like BigInteger does and perform some high-bit-level(?) operations.
Page Index Toggle Pages: 1