De Bruijn algorithm binary digit count 64bits C#

前端 未结 4 2202
陌清茗
陌清茗 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条回答
  •  囚心锁ツ
    2021-01-04 21:41

    Edit: This solution is not recommanded as it requires branching for Zero.

    After reading Niklas B's answer I spent a few hours on researching this, and realize all magic multiplicator has to be in the last nth in order to suit for 64-elements lookup table (I don't have the necessary knowledge to explain why).

    So I used exactly the same generator mentioned by that answer to find the last sequence, here is the C# code:

    // used generator from http://chessprogramming.wikispaces.com/De+Bruijn+Sequence+Generator
    static readonly byte[] DeBruijnMSB64table = new byte[]
    {
        0 , 47, 1 , 56, 48, 27, 2 , 60,
        57, 49, 41, 37, 28, 16, 3 , 61,
        54, 58, 35, 52, 50, 42, 21, 44,
        38, 32, 29, 23, 17, 11, 4 , 62,
        46, 55, 26, 59, 40, 36, 15, 53,
        34, 51, 20, 43, 31, 22, 10, 45,
        25, 39, 14, 33, 19, 30, 9 , 24,
        13, 18, 8 , 12, 7 , 6 , 5 , 63,
    };
    // the cyclc number has to be in the last 16th of all possible values
    // any beyond the 62914560th(0x03C0_0000) should work for this purpose
    const ulong DeBruijnMSB64multi = 0x03F79D71B4CB0A89uL; // the last one
    public static byte GetMostSignificantBit(this ulong value)
    {
        value |= value >> 1;
        value |= value >> 2;
        value |= value >> 4;
        value |= value >> 8;
        value |= value >> 16;
        value |= value >> 32;
    
        return DeBruijnMSB64table[value * DeBruijnMSB64multi >> 58];
    }
    

提交回复
热议问题