2-8 K& R C锻炼有什么不对?

时间:2015-07-10 16:41:35

标签: c

我正在做这个练习

  

写一个函数rightrot(x,n),它返回整数x的值,向右旋转n位位置。

但是当我尝试运行它时,我无法得到我期望的结果。

#include"stdio.h"    
int most_signficant_bit(unsigned x){
        int bitpos;
        for(bitpos = -1; x!=0;++bitpos){
            x=x>>1;
        }
        return bitpos;
    }
unsigned rightrot(unsigned x, unsigned n){
        int bitpos;
        bitpos  = most_signficant_bit(x);

       x = ((x>>n)|(((~(~0<<n))&x)<<(bitpos-n)));
        return x;
    }
int main(int argc, char const *argv[]) {
        unsigned int c1;
        c1 = 0xff1;

        printf("bitfield  %x "
        " after rightrot %x \n",c1, rightrot(c1, 4) );
        return 0;
    }

我知道(x>>n)会移动位域&#39; n&#39;向右0000 1111 1111次复制&#39; n&#39;来自该空间的较少有效位。
(~(~0<<n))&x)复制n个较低有效位(1111 1111 0001&amp; 0000 0000 1111 = 0000 0000 0001),然后将这些位移到正确的位置
{{ 1}}以及在<<(bitpos-n)中复制或复制这些位之后。
但我得到x而不是0xff或二进制0x1ff而不是0000 1111 1111

那有什么不对?

2 个答案:

答案 0 :(得分:5)

 x = ((x>>n)|(((~(~0<<n))&x)<<(bitpos-n)));

你认为不应该这样做

 x = ((x>>n)|(((~(~0<<n))&x)<<(bitpos-n+1)));

答案 1 :(得分:0)

我认为这个表达

x = ((x>>n)|(((~(~0<<n))&x)<<(bitpos-n+1)));

过于复杂且难以辨认。:)

此外,使用此表达式的函数实现无效,因为n可能比unsigned int类型的对象中的位数更多。

该功能可以按照以下方式编写,如演示程序

所示
#include <stdio.h>
#include <limits.h>

unsigned int rotate_right( unsigned int x, size_t n )
{
    const size_t N = CHAR_BIT * sizeof( int );

    n %= N;

    return x >> n | x << ( N - n );
}

int main( void )
{
    unsigned int x = 0x12345678;

    size_t n = CHAR_BIT * sizeof( int );

    do 
    { 
        printf( "%x\n", x ); 
        x = rotate_right( x, CHAR_BIT / 2 );
    } while ( n -= CHAR_BIT / 2 );
}    

程序输出

12345678
81234567
78123456
67812345
56781234
45678123
34567812
23456781

您可以使用以下函数删除标头<limits.h>并计算unsigned int类型对象中的位数

size_t bit_count()
{
    size_t n = 0;

    for ( unsigned int i = ~0u; i; i >>= 1 ) ++n;

    return n;
}