What is the fastest/most efficient way to find the highest set bit (msb) in an integer in C?

后端 未结 27 3298
终归单人心
终归单人心 2020-11-22 03:35

If I have some integer n, and I want to know the position of the most significant bit (that is, if the least significant bit is on the right, I want to know the position of

27条回答
  •  暖寄归人
    2020-11-22 04:01

    As the answers above point out, there are a number of ways to determine the most significant bit. However, as was also pointed out, the methods are likely to be unique to either 32bit or 64bit registers. The stanford.edu bithacks page provides solutions that work for both 32bit and 64bit computing. With a little work, they can be combined to provide a solid cross-architecture approach to obtaining the MSB. The solution I arrived at that compiled/worked across 64 & 32 bit computers was:

    #if defined(__LP64__) || defined(_LP64)
    # define BUILD_64   1
    #endif
    
    #include 
    #include   /* for uint32_t */
    
    /* CHAR_BIT  (or include limits.h) */
    #ifndef CHAR_BIT
    #define CHAR_BIT  8
    #endif  /* CHAR_BIT */
    
    /* 
     * Find the log base 2 of an integer with the MSB N set in O(N)
     * operations. (on 64bit & 32bit architectures)
     */
    int
    getmsb (uint32_t word)
    {
        int r = 0;
        if (word < 1)
            return 0;
    #ifdef BUILD_64
        union { uint32_t u[2]; double d; } t;  // temp
        t.u[__FLOAT_WORD_ORDER==LITTLE_ENDIAN] = 0x43300000;
        t.u[__FLOAT_WORD_ORDER!=LITTLE_ENDIAN] = word;
        t.d -= 4503599627370496.0;
        r = (t.u[__FLOAT_WORD_ORDER==LITTLE_ENDIAN] >> 20) - 0x3FF;
    #else
        while (word >>= 1)
        {
            r++;
        }
    #endif  /* BUILD_64 */
        return r;
    }
    

提交回复
热议问题