Search code examples
c#x86bit-manipulationleading-zero

Fast way of finding most and least significant bit set in a 64-bit integer


There are a lot of questions about this on StackOverflow. A lot. However I cannot find an answer that:

  • Works in C#
  • Works for 64-bit integers (as opposed to 32-bit)

Faster than:

private static int Obvious(ulong v)
{
    int r = 0;
    while ((v >>= 1) != 0) 
    {
        r++;
    }
    return r;
}

Or even

int r = (int)(Math.Log(v,2));

I'm assuming a 64-bit Intel CPU here.

One useful reference is the Bit Hacks page and another is fxtbook.pdf However, while these gives useful direction to approach the problem, they do not give a ready answer.

I'm after a re-usable function that can do something similar to _BitScanForward64 and _BitScanReverse64 only for C#.


Solution

  • As per my comment, this is a function in C# to count leading zero bits modified for a 64 bit integer.

    public static UInt64 CountLeadingZeros(UInt64 input)
    {
        if (input == 0) return 64;
    
        UInt64 n = 1;
    
        if ((input >> 32) == 0) { n = n + 32; input = input << 32; }
        if ((input >> 48) == 0) { n = n + 16; input = input << 16; }
        if ((input >> 56) == 0) { n = n + 8; input = input << 8; }
        if ((input >> 60) == 0) { n = n + 4; input = input << 4; }
        if ((input >> 62) == 0) { n = n + 2; input = input << 2; }
        n = n - (input >> 63);
    
        return n;
    }
    

    UPDATE:
    If you're using a newer version of C#, check to see if this is built-in per the answer below. https://stackoverflow.com/a/61141435/1587755