Jump to content
Tuts 4 You

Getting most significant bits...


CodeExplorer

Recommended Posts

Posted (edited)

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
Posted (edited)

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
Posted

@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!
 

Posted (edited)

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
Posted

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

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
×
×
  • Create New...