Assuming the 64bit integer 0x000000000000FFFF
which would be represented as
00000000 00000000 00000000 00000000
00000000 00000000 >11111111 11111111
How do I find the amount of unset bits to the left of the most significant set bit (the one marked with >) ?
Based on: http://www.hackersdelight.org/HDcode/nlz.c.txt
If you'd like a version that allows you to keep your lunch down, here you go:
As you'll see, you can save cycles on this by careful analysis of the assembler, but the strategy here is not a terrible one. The while loop will operate Lg[64]=6 times; each time it will convert the problem into one of counting the number of leading bits on an integer of half the size. The if statement inside the while loop asks the question: "can i represent this integer in half as many bits", or analogously, "if i cut this in half, have i lost it?". After the if() payload completes, our number will always be in the lowest n bits. At the final stage, v is either 0 or 1, and this completes the calculation correctly.
If you are dealing with unsigned integers, you could do this:
I don't know how it will compare in performance to the loop and count methods that have already been offered because log2() could be expensive.
Edit:
This could cause some problems with high-valued integers since the
log2()
function is casting todouble
and some numerical issues may arise. You could use thelog2l()
function that works withlong double
. A better solution would be to use an integerlog2()
function as in this question.Where
count_bits_set
is the fastest version of counting bits you can find. See https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel for various bit counting techniques.I'm not sure I understood the problem correctly. I think you have a 64bit value and want to find the number of leading zeros in it.
One way would be to find the most significant bit and simply subtract its position from 63 (assuming lowest bit is bit 0). You can find out the most significant bit by testing whether a bit is set from within a loop over all 64 bits.
Another way might be to use the (non-standard)
__builtin_clz
in gcc.I agree with the binary search idea. However two points are important here:
The following template stuff finds the MSB correctly of any unsigned type variable.
Same idea as user470379's, but counting down ...Assume all 64 bits are unset. While value is larger than 0 keep shifting the value right and decrementing number of unset bits: