Help - How to get the most significant bit

Started by
32 comments, last by zeelot 18 years, 9 months ago
We are developing game engine on ARM CPU... Here is a problem we have. There is a binary number (stuff like "00101011"). We need to know WHICH bit is its MSB (Most Significant Bit). In the above example, the answer is "6". The problem is: Is it possible to figure out the answer without FOR/WHILE or LOG... - bit operations are preferred - O(1) operation Thanks everybody zEELOt
Advertisement
How about something like this... at least it's a start.

int done = 0;int bit = 17;int testPattern = 0xFF; // or whatever in hex codeint mask = 0x80;while(!done){     done = testPattern & mask;     mask >>= 1;     bit--;}return bit;
.
If you are only dealing with 8 bits, you could just store all the values in a lookup table for the fastest execution; unless there's a really obvious solution that I haven't spotted at first glance.
I'll learn to read one of these days... WITHOUT while loops... a look up table would work fine... not sure what else...
.
msb = number;msb |= msb >> 1;msb |= msb >> 2;msb |= msb >> 4;msb |= msb >> 8;msb |= msb >> 16;msb = (++msb)>>1;


ok?

There are faster ways to do it tho.... (many faster ways).

From,
Nice coder
Click here to patch the mozilla IDN exploit, or click Here then type in Network.enableidn and set its value to false. Restart the browser for the patches to work.
A binary search type approach could yield O(log n). That's probably the best you can do without a huge lookup table.
.
To explain.

Lets say you had the number 0010001101

First stage
0010001101 |= 0010001101 >> 1
= 0010001101 | 0001000110

0010001101
0001000110
----------
0011001111

Second stage
0011001111 | 0011001111 >> 2
0011001111
0000110011
0011111111

Next stage....
(they don't make any difference, because of the number. you could use some special cases to increase its speed a bit, but they might not work well (speed vs clutter)).

And the end.

0011111111
+ 1
=
0100000000
Leftshift one
0010000000
Compare to our number
0010001101

See any similarities?
Yes, its its msb.

From,
Nice coder
Click here to patch the mozilla IDN exploit, or click Here then type in Network.enableidn and set its value to false. Restart the browser for the patches to work.
Quote:Original post by ascorbic
A binary search type approach could yield O(log n). That's probably the best you can do without a huge lookup table.


My current version does 12 ops (all bitwise) for a 32 bit number. (two more for a 64 bit number, ect)

For your o(log n) solution to be better, you'd need a S of less then

S(5) < 12
S < 12/5
S < 2.4

So, you need 2.4 operations per iteration AT MOST. (ie. to break even).

A single if is more then 2.4 operations.

There was a thread about this.... (next biggest power of two... thread, i don't have a link and i'm not gonna battle google to find it).

From,
Nice coder
Click here to patch the mozilla IDN exploit, or click Here then type in Network.enableidn and set its value to false. Restart the browser for the patches to work.
ascorbic: How would you do a binary search?
Nice Coder: That's a clever idea, but you'd better test it to be sure that it's any faster than a simple loop. Also it doesn't answer the question.

zeelot: What do you need the msb for? Does it really make any difference if you use the method ascorbic posted?
Quote:Original post by Nice Coder
msb = number;msb |= msb >> 1;msb |= msb >> 2;msb |= msb >> 4;msb |= msb >> 8;msb |= msb >> 16;msb = (++msb)>>1;



Doesn't work btw.

100000b>>0 | 100000b>>1 | 100000b>>2b | 100000b>>4b =
100000b | 10000b | 1000b | 10b =
111010b

You need to have all of the bits:
msb |= msb >> 1;msb |= msb >> 2;msb |= msb >> 3;  // <---msb |= msb >> 4;msb |= msb >> 5;  // <---....


On ARM I think you can code each line with one instruction. A loop would take 3 instructions, at an average of 1.5 per bit, assuming all integers are equally likely and would also give the answer that was asked for, ie. the MSB-bit. Due to instruction scheduling and caching, it would be best to test either case, or just use the loop for simplicity and smaller size.

This topic is closed to new replies.

Advertisement