Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Let's take the number 10 as an example. It can be stated in binary as follows:</p> <pre><code> 00000000000000000000000000010100 </code></pre> <p>First we "smear" the most significant bit over the lower bit positions by right shifting and bitwise-ORing over itself.</p> <pre><code> 00000000000000000000000000010100 or 00000000000000000000000000001010 (right-shifted by 1) is 00000000000000000000000000011100 </code></pre> <p>then</p> <pre><code> 00000000000000000000000000011100 or 00000000000000000000000000000111 (right-shifted by 2) is 00000000000000000000000000011111 </code></pre> <p>Here, because it's a small number, we've already completed the job, but by repeating the process right up to a right shift of 16 bits, we can ensure that for any 32-bit number, we have set all of the bits from 0 to the MSB of the original number to 1.</p> <p>Now, if we count the number of 1s in our "smeared" result, we can simply subtract it from 32, and we are left with the number of leading zeros in the original value.</p> <p>How do we count the number of set bits in an integer? <a href="http://aggregate.org/MAGIC/#Population%20Count%20(Ones%20Count)" rel="nofollow noreferrer">This page</a> has a magical algorithm for doing just that ("<em>a variable-precision SWAR algorithm to perform a tree reduction</em>"... if you get it, you're cleverer than me!), which translates to C# as follows:</p> <pre><code>int PopulationCount(int x) { x -= ((x &gt;&gt; 1) &amp; 0x55555555); x = (((x &gt;&gt; 2) &amp; 0x33333333) + (x &amp; 0x33333333)); x = (((x &gt;&gt; 4) + x) &amp; 0x0f0f0f0f); x += (x &gt;&gt; 8); x += (x &gt;&gt; 16); return (x &amp; 0x0000003f); } </code></pre> <p>By inlining this method with our "smearing" method above, we can produce a very fast, loop-free and conditional-free method for counting the leading zeros of an integer.</p> <pre><code>int LeadingZeros(int x) { const int numIntBits = sizeof(int) * 8; //compile time constant //do the smearing x |= x &gt;&gt; 1; x |= x &gt;&gt; 2; x |= x &gt;&gt; 4; x |= x &gt;&gt; 8; x |= x &gt;&gt; 16; //count the ones x -= x &gt;&gt; 1 &amp; 0x55555555; x = (x &gt;&gt; 2 &amp; 0x33333333) + (x &amp; 0x33333333); x = (x &gt;&gt; 4) + x &amp; 0x0f0f0f0f; x += x &gt;&gt; 8; x += x &gt;&gt; 16; return numIntBits - (x &amp; 0x0000003f); //subtract # of 1s from 32 } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload