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

后端 未结 27 2729
终归单人心
终归单人心 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:20

    Note that what you are trying to do is calculate the integer log2 of an integer,

    #include 
    #include 
    
    unsigned int
    Log2(unsigned long x)
    {
        unsigned long n = x;
        int bits = sizeof(x)*8;
        int step = 1; int k=0;
        for( step = 1; step < bits; ) {
            n |= (n >> step);
            step *= 2; ++k;
        }
        //printf("%ld %ld\n",x, (x - (n >> 1)) );
        return(x - (n >> 1));
    }
    

    Observe that you can attempt to search more than 1 bit at a time.

    unsigned int
    Log2_a(unsigned long x)
    {
        unsigned long n = x;
        int bits = sizeof(x)*8;
        int step = 1;
        int step2 = 0;
        //observe that you can move 8 bits at a time, and there is a pattern...
        //if( x>1<1<1<1L<1L<<(step+step2); ) {
            step+=1;
            //printf("step %d\n",step+step2);
        }
        printf("log2(%ld) %d\n",x,step+step2);
        return(step+step2);
    }
    

    This approach uses a binary search

    unsigned int
    Log2_b(unsigned long x)
    {
        unsigned long n = x;
        unsigned int bits = sizeof(x)*8;
        unsigned int hbit = bits-1;
        unsigned int lbit = 0;
        unsigned long guess = bits/2;
        int found = 0;
    
        while ( hbit-lbit>1 ) {
            //printf("log2(%ld) %d<%d<%d\n",x,lbit,guess,hbit);
            //when value between guess..lbit
            if( (x<=(1L<(1L< 1<<%d %ld\n",x,guess,1L<(1L<

    Another binary search method, perhaps more readable,

    unsigned int
    Log2_c(unsigned long x)
    {
        unsigned long v = x;
        unsigned int bits = sizeof(x)*8;
        unsigned int step = bits;
        unsigned int res = 0;
        for( step = bits/2; step>0; )
        {
            //printf("log2(%ld) v %d >> step %d = %ld\n",x,v,step,v>>step);
            while ( v>>step ) {
                v>>=step;
                res+=step;
                //printf("log2(%ld) step %d res %d v>>step %ld\n",x,step,res,v);
            }
            step /= 2;
        }
        if( (x>(1L<

    And because you will want to test these,

    int main()
    {
        unsigned long int x = 3;
        for( x=2; x<1000000000; x*=2 ) {
            //printf("x %ld, x+1 %ld, log2(x+1) %d\n",x,x+1,Log2(x+1));
            printf("x %ld, x+1 %ld, log2_a(x+1) %d\n",x,x+1,Log2_a(x+1));
            printf("x %ld, x+1 %ld, log2_b(x+1) %d\n",x,x+1,Log2_b(x+1));
            printf("x %ld, x+1 %ld, log2_c(x+1) %d\n",x,x+1,Log2_c(x+1));
        }
        return(0);
    }
    

提交回复
热议问题