Compute fast log base 2 ceiling

前端 未结 14 636
栀梦
栀梦 2020-11-28 11:35

What is a fast way to compute the (long int) ceiling(log_2(i)), where the input and output are 64-bit integers? Solutions for signed or unsigned integers are ac

14条回答
  •  渐次进展
    2020-11-28 12:10

    #include "stdafx.h"
    #include "assert.h"
    
    int getpos(unsigned __int64 value)
    {
        if (!value)
        {
          return -1; // no bits set
        }
        int pos = 0;
        if (value & (value - 1ULL))
        {
          pos = 1;
        }
        if (value & 0xFFFFFFFF00000000ULL)
        {
          pos += 32;
          value = value >> 32;
        }
        if (value & 0x00000000FFFF0000ULL)
        {
          pos += 16;
          value = value >> 16;
        }
        if (value & 0x000000000000FF00ULL)
        {
          pos += 8;
          value = value >> 8;
        }
        if (value & 0x00000000000000F0ULL)
        {
          pos += 4;
          value = value >> 4;
        }
        if (value & 0x000000000000000CULL)
        {
          pos += 2;
          value = value >> 2;
        }
        if (value & 0x0000000000000002ULL)
        {
          pos += 1;
          value = value >> 1;
        }
        return pos;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {    
        assert(getpos(0ULL) == -1); // None bits set, return -1.
        assert(getpos(1ULL) == 0);
        assert(getpos(2ULL) == 1);
        assert(getpos(3ULL) == 2);
        assert(getpos(4ULL) == 2);
        for (int k = 0; k < 64; ++k)
        {
            int pos = getpos(1ULL << k);
            assert(pos == k);
        }
        for (int k = 0; k < 64; ++k)
        {
            int pos = getpos( (1ULL << k) - 1);
            assert(pos == (k < 2 ? k - 1 : k) );
        }
        for (int k = 0; k < 64; ++k)
        {
            int pos = getpos( (1ULL << k) | 1);
            assert(pos == (k < 1 ? k : k + 1) );
        }
        for (int k = 0; k < 64; ++k)
        {
            int pos = getpos( (1ULL << k) + 1);
            assert(pos == k + 1);
        }
        return 0;
    }
    

提交回复
热议问题