C 编程语言的练习 2-7 :
编写一个函数
invert(x,p,n)
,返回从反转位置开始x
的n
位p
(即,1 变为 0,反之亦然),其他保持不变。
我理解这样的问题:我有 182 是101(101)10
二进制的,括号中的部分必须反转而不改变其余部分。返回值应该是10101010
then,即十进制的 170。
这是我的尝试:
#include <stdio.h>
unsigned int getbits(unsigned int bitfield, int pos, int num);
unsigned int invert(unsigned int bitfield, int pos, int num);
int main(void)
{
printf("%d\n", invert(182, 4, 3));
return 0;
}
/* getbits: get num bits from position pos */
unsigned int getbits(unsigned int bitfield, int pos, int num)
{
return (bitfield >> (pos+1-n)) & ~(~0 << num);
}
/* invert: flip pos-num bits in bitfield */
unsigned int invert(unsigned int bitfield, int pos, int num)
{
unsigned int mask;
unsigned int bits = getbits(bitfield,pos,num);
mask = (bits << (num-1)) | ((~bits << (pos+1)) >> num);
return bitfield ^ mask;
}
这似乎是正确的(对我来说),但invert(182, 4, 3)
输出536870730
. getbits()
工作正常(直接来自书中)。我写下了我分配给的表达式中发生的事情y
:
(00000101 << 2) | ((~00000101 << 5) >> 3) -- 000000101 is the part being flipped: 101(101)10
00010100 | ((11111010 << 5) >> 3)
00010100 | (01000000 >> 3)
00010100 | 00001000
= 00011100
10110110 (182)
^ 00011100
----------
= 10101010 (170)
应该是正确的,但事实并非如此。我发现这是出错的地方:((~xpn << (p+1)) >> n)
. 我不明白怎么做。
另外,我不知道这段代码有多通用。我的首要任务是让这个案子运作起来。也欢迎在这个问题上提供帮助。