Jump to content
Tuts 4 You
CodeExplorer

Getting most significant bits...

Recommended Posts

CodeExplorer

Getting most significant bits...
I could only think of this:

#define GetLSBs(x,n) (x&((1<<n)-1))

unsigned int GetMSBs(unsigned int x,unsigned n)  // n number of bits to get from i = 0
{  // n = numbers of bits to get
unsigned int LSB = GetLSBs(x,32-n);
unsigned int MSB = x-LSB;
return MSB;

}

I've thinked of getting MSB with "and" instruction; anyway I've failed to get bits mask:
first bit, first two bits, first 3 bits ...:
1000  // 8
1100  // 12
1110  // 14
1111  // 15

 

Edited by CodeExplorer (see edit history)

Share this post


Link to post
Share on other sites
tonyweb

I guess you have to right shift the result, if I understood correctly what you need :)

Something like this should work (C# code btw)

         uint GetMSBs(uint x, int n, int totalBits)  // n number of bits to get from i = 0
        {  
            // n = numbers of bits to get
            uint msb = (x >> (totalBits - n));
                 msb = (uint) ( msb & ((1<<n)-1) );
            
            return msb;
        } 

 

with totalBits = 32 for dwords.

[EDIT]

Or, if you need the value for the bit mask, just shift-left the lsb mask (i.e. "((1<<n)-1 )")  of (totalBits - n) places;

Regards,
Tony

 

 

Edited by tonyweb (see edit history)

Share this post


Link to post
Share on other sites
CodeExplorer

@tonyweb: Thank you, that was exactly what I needed!

Here is the Pelles C version:

unsigned int GetMSBs(unsigned int x, unsigned int n)
// n number of bits to get from i = 0
{
// n = numbers of bits to get
unsigned int msb = (x >> (32 - n));  // 32 = number of bits
msb = (unsigned int) (msb & ((1<<n)-1));

return msb;
}

Your solution will get MSB bits in low part (since they are shifted) which is 100% OK.
Thank you once again.

Another question: I don't understand why the last part is needed: msb = (uint) ( msb & ((1<<n)-1) );
seems to works ok even without it!
 

Share this post


Link to post
Share on other sites
tonyweb

Last part takes into account the shifting of "negative" numbers ...
If the MSB bit is set (i.e. x & 0x80000000 != 0), when shifting the sign might be preserved, so it would result in an incorrect value without the proper masking.

Regards,
Tony

[EDIT] But, given you're dealing with unsigned vars, maybe it's an overkill :)

 

Edited by tonyweb (see edit history)

Share this post


Link to post
Share on other sites
atom0s

If you are just getting the MSB that is set, you can use the 'BSR' instruction. https://c9x.me/x86/html/file_module_x86_id_20.html

If using Visual Studio there is an intrinsic version of this: https://docs.microsoft.com/en-us/cpp/intrinsics/bitscanreverse-bitscanreverse64?view=vs-2017

For other raw format versions, there's a bunch of examples suggested on StackOverflow for similar here:

https://stackoverflow.com/questions/671815/what-is-the-fastest-most-efficient-way-to-find-the-highest-set-bit-msb-in-an-i

  • Thanks 1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×