我正在做这个练习
写一个函数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
。
那有什么不对?
答案 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;
}