De Bruijn algorithm binary digit count 64bits C#

前端 未结 4 2296
陌清茗
陌清茗 2021-01-04 21:26

Im using the \"De Bruijn\" Algorithm to discover the number of digits in binary that a big number (up to 64bits) has.

For example:

  • 1022 has 10 digits i
4条回答
  •  梦毁少年i
    2021-01-04 22:00

    When I looked into this a while back for 32 bits, the DeBruijn sequence method was by far the fastest. See https://stackoverflow.com/a/10150991/56778

    What you could do for 64 bits is split the number into two 32-bit values. If the high 32 bits is non-zero, then run the DeBruijn calculation on it, and then add 32. If the high 32 bits is zero, then run the DeBruijn calculation on the low 32 bits.

    Something like this:

    int NumBits64(ulong val)
    {
        if (val > 0x00000000FFFFFFFFul)
        {
            // Value is greater than largest 32 bit number,
            // so calculate the number of bits in the top half
            // and add 32.
            return 32 + GetLog2_DeBruijn((int)(val >> 32));
        }
        // Number is no more than 32 bits,
        // so calculate number of bits in the bottom half.
        return GetLog2_DeBruijn((int)(val & 0xFFFFFFFF));
    }
    
    int GetLog2_DeBruijn(int val)
    {
        uint32 v = (uint32)val;
        int r;      // result goes here
    
        static const int MultiplyDeBruijnBitPosition[32] = 
        {
            0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
            8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
        };
    
        v |= v >> 1; // first round down to one less than a power of 2 
        v |= v >> 2;
        v |= v >> 4;
        v |= v >> 8;
        v |= v >> 16;
    
        r = MultiplyDeBruijnBitPosition[(uint32_t)(v * 0x07C4ACDDU) >> 27];
        return r;
    }
    

提交回复
热议问题