• Join
  • Sign In with my.TI Login
Texas Instruments
  • Products
  • Applications
  • Tools & Software
  • Support & Community
  • Sample & Buy
  • About TI
Sample & Purchase Cart Sample & Purchase Cart
  • Search
  • Advanced
TI E2E™ Community
  • Support Forums
  • Blogs
  • Groups
  • Videos
  • 简体中文
  • More ...
TI Home » TI E2E Community » Support Forums » Microcontrollers » MSP430™ Microcontrollers » MSP430 Ultra-Low Power 16-bit Microcontroller Forum » Algorithm for getting LSB position of a variable
Share
MSP430™ Microcontrollers
  • Forum
  • Announcements
  • E2E Wiki
Options
  • Subscribe via RSS
MSP430 Resources
  • MSP430 Product Folder
  • MSP-EXP430G2 - MSP430 LaunchPad Value Line Development kit
  • MSP430 Getting Started Guide
  • MSP430 Microcontroller Projects
  • More Resources >
  • Forums

    Algorithm for getting LSB position of a variable

    This question is answered
    Leo Hendrawan
    Posted by Leo Hendrawan
    on Jul 23 2012 08:22 AM
    Mastermind27310 points

    Hi all,

    just want to ask whether someone knows a very fast algoirthm to get the LSB position of a 16/32bit variable?

    Example:

    0x0013 -> LSB position: 0 (bit 0)

    0x00A8 -> LSB position 3 (bit 3)

    0x00C0 -> LSB position 6 (bit 6)

    Tried to google but couldn't find anything. 

    Btw, i don't want to use big lookup table for this.

    Thanks

    Regards,

    Leo Hendrawan

    LSB position
    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    All Replies
    • Emanuele Bellocchia
      Posted by Emanuele Bellocchia
      on Jul 23 2012 10:52 AM
      Verified Answer
      Verified by Leo Hendrawan
      Prodigy190 points

      You can simply shift right the variable until the first bit is equal to 1:

      int tmp = var;  // Temporary copy of the variable
      int cnt = 0;      // Bit counter
      if (tmp != 0)    // To avoid infinite loops
          while (!(tmp & 0x01))
          {
              tmp >>= 1;
              cnt++;
          }
      // 'cnt' contains the LSB position

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Leo Hendrawan
      Posted by Leo Hendrawan
      on Jul 23 2012 13:51 PM
      Mastermind27310 points

      Hi Emanuelle,

      thanks for the reply. I know this simple method. What i need is something which works really fast.

      Regards,

      Leo Hendrawan

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Andy Neil
      Posted by Andy Neil
      on Jul 23 2012 15:44 PM
      Guru31975 points

      lhend
      What i need is something which works really fast

      What, exactly, do you mean by, "really fast"?

      The loop would only have to spin a max of 16/32 times - so it's not exactly "slow"!

      Other than a lookup table, a string of ifs could well be fastest - especially if you have some prior knowledge of the "most likely" outcome(s)...

       

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Leo Hendrawan
      Posted by Leo Hendrawan
      on Jul 23 2012 16:13 PM
      Mastermind27310 points

      Hi Andy,

      thanks for the reply. Actually i am developing a light-weight scheduler system for MSP430 value line devices. Should be ready soon, but i want to do some optimizations. One of them is basically covered in this question. I have a 16 bit variable in my scheduler system which represents the tasks which are ready to be executed.

      What i want is something like these:

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

      for example i found that:: x &= x - 1 will give you the LSB only bit set of the variable x. But what i want is something different, i want to get the position of the LSB.

      Regards,

      Leo Hendrawan

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Norman Wong
      Posted by Norman Wong
      on Jul 23 2012 18:37 PM
      Verified Answer
      Verified by Leo Hendrawan
      Guru14930 points

      Binary search and lookup:

      static const signed char g_lsb[16] =
      {
        4, /* 0b0000 *//*Error condition?*/
        0, /* 0b0001 */
        1, /* 0b0010 */
        0, /* 0b0011 */
        2, /* 0b0100 */
        0, /* 0b0101 */
        1, /* 0b0110 */
        0, /* 0b0111 */
        3, /* 0b1000 */
        0, /* 0b1001 */
        1, /* 0b1010 */
        0, /* 0b1011 */
        2, /* 0b1100 */
        0, /* 0b1101 */
        1, /* 0b1110 */
        0, /* 0b1111 */
      };

      int lsb_pos(unsigned int x)
      {
        int base;

        if(x & 0x00FF)
          base = (x & 0x000F) ? 0 : 4;
        else
          base = (x & 0x0F00) ? 8 : 12;

        x >>= base;
        x  &= 0xF;
        return(g_lsb[x] + base);
      }

      The above should be a fixed cost algorithm. Regardless of the value of n.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Leo Hendrawan
      Posted by Leo Hendrawan
      on Jul 24 2012 02:24 AM
      Mastermind27310 points

      Hi Norman,

      yes, i thought also about binary search with something like this. I'll let the discussion to be opened waiting for some other inputs.

      thanks again.

      Regards,

      Leo Hendrawan

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • old_cow_yellow
      Posted by old_cow_yellow
      on Jul 24 2012 09:25 AM
      Guru25735 points

      lhend
      ... for example i found that:: x &= x - 1 will give you the LSB only bit set of the variable x. But what i want is something different, i want to get the position of the LSB.

      I do not get it. But I think y = (x ^ (x - 1)) + 1 will give you 2**(the position of the LSB)

      For example: x = 0x30C0; the LSB is BIT 7

      y = (0x30C0 ^ (0x30BF)) + 1 = 0x007F + 1 = 0x0080; which is 2**7

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Leo Hendrawan
      Posted by Leo Hendrawan
      on Jul 24 2012 10:13 AM
      Mastermind27310 points

      Hi OCY,

      old_cow_yellow

      lhend
      ... for example i found that:: x &= x - 1 will give you the LSB only bit set of the variable x. But what i want is something different, i want to get the position of the LSB.

      I do not get it. 

      For example let's say for the sake of simplicity, we take number 0xF4 = 1111 0100 bin. to get the LSB (not the position), we take -(0xF4) = 0xC0 -> using 2 complements.

      If we then do 0xF4 & 0xC0, this will result to 0x04, which is basically the LSB. But what i want is the bit position which in this case 2 (bit 2).

      Regards,

      Leo Hendrawan

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Jeff Tenney
      Posted by Jeff Tenney
      on Jul 24 2012 12:34 PM
      Verified Answer
      Verified by Leo Hendrawan
      Guru10795 points

      Hi Leo,

      The first "trick" you mentioned actually clears the least-significant set bit.  Here is the longhand version of the trick:

      x = x & (x-1);

      For example, take the number 0xF4 = 1111 0100.  Bitwise AND with 0xF3 = 1111 0011.  Gives 0xF0.  We cleared the least-significant set bit.

      Then you alluded to a second "trick" without really showing it first:

      x = x & -x;

      This trick clears everything except the least-significant set bit (just like OCYs method).

      For example, take the number 0xF4 = 1111 0100.  -0xF4 is 0x0C = 0000 1100.  Anded together you get 0x04.

      However, as you say, you really want to convert that 0x04 into its bit position.  That is a log2 function.  Many microprocessors and DSPs have a native log2 instruction.  That's because there is no quick arithmetic transform between these two domains.

      Jeff

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Leo Hendrawan
      Posted by Leo Hendrawan
      on Jul 24 2012 15:55 PM
      Mastermind27310 points

      Ups..

      you're right Jeff... it is x &= -x which will give the LSB set only in the variable, sorry for the confusion :)

      Regards,

      Leo Hendrawan

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Jens-Michael Gross
      Posted by Jens-Michael Gross
      on Jul 25 2012 09:00 AM
      Verified Answer
      Verified by Leo Hendrawan
      Guru140135 points

      the fastest thing to get the position of the LSB is a lookup table. Takes 65536 bytes for a 16 bit value.
      However, next optimizaiton step is only a 256 byte lookup table and a bit more code.

      const unsigned char lookup[256] = {0,1,2,1,3,1,2,1,4,...};

      int x = lookup[y&0xff];
      if(!x) x= 8+ lookup[y>>8];
      x--;

       then contains the bit number of the LSB or -1 if there was no bit set.

      For a 32 bit value, two more lines have to be added, similar to the second one.

      I don't think you can get it faster.

      _____________________________________
      Before posting bug reports or ask for help, do at least quick scan over this article. It applies to any kind of problem reporting. On any forum. And/or look here.
      If you cannot discuss your problem in the public, feel free to start a private conversation: click on my name and then 'start conversation'. But please do so only if you really cannot do it in a public thread, as I usually read all threads. And I prefer to answer where others can profit from it (or contribute to it) too.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Leo Hendrawan
      Posted by Leo Hendrawan
      on Jul 25 2012 09:08 AM
      Mastermind27310 points

      Hi JMG,

      thanks for the input also. Yes lookup table would be the fastest way, but i can't afford that (even for the 256 bytes table). My complete scheduler (with all features enabled, but no application code) now only consumes less than 1 KB. Giving away hundreds of bytes for the lookup table would be too much.

      It seems there is no real silver bullet in this case, but thanks again for the input, guys.

      Regards,

      Leo Hendrawan

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Jens-Michael Gross
      Posted by Jens-Michael Gross
      on Jul 25 2012 10:50 AM
      Guru140135 points

      lhend
      i can't afford that (even for the 256 bytes table)

      Well, you can go for nibbles with a 16 bytes table. It adds to the execution time but significantly reduces size, as you can test 4 bits at a time.

      Of course, doing the lookup table approach in assembly will allow for some more efficiency and save some more cycles and bytes.

      _____________________________________
      Before posting bug reports or ask for help, do at least quick scan over this article. It applies to any kind of problem reporting. On any forum. And/or look here.
      If you cannot discuss your problem in the public, feel free to start a private conversation: click on my name and then 'start conversation'. But please do so only if you really cannot do it in a public thread, as I usually read all threads. And I prefer to answer where others can profit from it (or contribute to it) too.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Leo Hendrawan
      Posted by Leo Hendrawan
      on Jul 25 2012 11:14 AM
      Mastermind27310 points

      Hi JMG,

      Jens-Michael Gross

      Of course, doing the lookup table approach in assembly will allow for some more efficiency and save some more cycles and bytes.

      This is a very good point which i also notice, that's why i am going to put this routine in the "portable" file which can be adapted to the hardware capability.

      Will let you know if i am ready to release the code (actually the code itself is finished, but i still need to make better documentation :) )

      Regards,

      Leo Hendrawan

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • SHau
      Posted by SHau
      on Jul 26 2012 04:11 AM
      Intellectual360 points

      Another compromise between speed and size would be:

      int FindLsb( int val) 
      {  
        if( val & 0x01)  return 1; 
        if( val & 0x02)  return 2;   
        if( val & 0x04)  return 3; 
                        .
                        .
        if( val & 0x80)  return 16;

        return 0;
      }

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    123
    TI E2E™ Community
    • Support Forums
    • Blogs
    • Videos
    • Groups
    • Site Support & Feedback
    • Settings
    TI E2E™ Community Groups
    • TI University Program
    • Make the Switch
    • Microcontroller Projects
    • Motor Drive & Control
    Other Communities
    • Deyisupport
    • Designsomething.org
    • beagleboard.org
    • TI on Element 14
    • TI on TechXchangeSM
    Other Technical & Support Resources
    • WEBENCH® Design Center
    • Product Information Centers
    • Technical Documents
    • TI Design Network
    • TI Technical Articles
    • TI Training

    All content and materials on this site are provided "as is". TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with regard to these materials, including but not limited to all implied warranties and conditions of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with respect to these materials. No license, either express or implied, by estoppel or otherwise, is granted by TI. Use of the information on this site may require a license from a third party, or a license from TI.

    Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms of Use of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms of Use of this site. TI, its suppliers and providers of content reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.

    Follow Us Texas Instruments on Facebook Texas Instruments on Twitter Texas Instruments on LinkedIn Texas Instruments on Google+
    TI Worldwide | Contact Us | my.TI Login | Site Map | Corporate Citizenship | mobile m.ti.com (Mobile Version)

    TI is a global semiconductor design and manufacturing company. Innovate with 100,000+ analog ICs and
    embedded processors, along with software, tools and the industry’s largest sales/support staff.

    © Copyright 1995-2013 Texas Instruments Incorporated. All rights reserved.
    Trademarks | Privacy Policy | Terms of Use