Get an array of the bit positions within a 64-bit integer

前端 未结 8 1366
囚心锁ツ
囚心锁ツ 2020-12-30 06:07

OK, it may sound a bit complicated, but this is what I\'m trying to do :

  • Take e.g. 10101010101
  • And return { 0, 2, 4, 6, 8, 10 }
相关标签:
8条回答
  • 2020-12-30 07:06

    I tried a naive version, which clocked in around 2-3x faster, but reserved()'d the vector first. On applying the reserve to the original algorithm, it beat the naive one.

    So I suspect that the vector operations are the bigger cost here, rather than the bit manipulation (or even the multiply used in the next-bit function).

    There are some other speed-ups to be had, regarding finding the lowest set bit. My local log2 version was poor, and the function given in the original post is not super cheap.

    Here's my best attempt:

    void bits(uint64 bitboard, vector<int> &res)
    {
        res.resize(64);
        int i = 0;
        while (bitboard)
        {
            int first;
            _BitScanForward64((DWORD *)&first, bitboard);
            res[i++] = first;
            bitboard &= ~(1ULL<<first);
        }
        res.resize(i);
    }
    

    Replaced the firstBit function with an asm intrinsic. Using the intrinsic gave a big boost here. (This is obviously not portable code, though I suspect a GCC variant shouldn't be too tricky).

    Also assumes the vector is reasonably persistent, rather than being dynamically allocated/copied all the time, and just resizes it appropriately.

    0 讨论(0)
  • 2020-12-30 07:09

    The fastest I can think of right now would be using a pre-generated map array of all numbers (it doesn't have to be all numbers, you can for example break the numbers in 8-bit or 16-bit parts and then concatenate the returned arrays with some proper additions to account for the actual position of the bits).

    0 讨论(0)
提交回复
热议问题