我在做那个练习
编写一个向右行的函数(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)将位字段'n‘时间移到右边的0000 1111 1111,以便从该空间复制“n”不太重要的比特。
(~(~0<<n))&x)复制n个不太重要的位(1111 1111 0001& 0000 0000 1111 = 0000 0000 0001),然后将这些位移到正确的位置
<<(bitpos-n)和在x中使用或复制这些位之后。
但是我用0xff代替了0x1ff,或者用二进制0000 1111 1111代替了0001 1111 1111。
那怎么回事?
发布于 2015-07-10 16:48:58
x = ((x>>n)|(((~(~0<<n))&x)<<(bitpos-n)));你不觉得不该这样吗?
x = ((x>>n)|(((~(~0<<n))&x)<<(bitpos-n+1)));发布于 2015-07-10 17:12:45
我觉得这句话
x = ((x>>n)|(((~(~0<<n))&x)<<(bitpos-n+1)));太复杂,无法读懂。)
此外,使用此表达式的函数实现是无效的,因为n可以比类型为无符号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;
}https://stackoverflow.com/questions/31346098
复制相似问题