“需要帮助理解”;getbits();K&;R C
在第2章,关于位运算符的部分(第2.9节),我很难理解其中一个示例方法是如何工作的 以下是提供的方法:“需要帮助理解”;getbits();K&;R C,c,operators,bit-manipulation,bit-shift,complement,C,Operators,Bit Manipulation,Bit Shift,Complement,在第2章,关于位运算符的部分(第2.9节),我很难理解其中一个示例方法是如何工作的 以下是提供的方法: unsigned int getbits(unsigned int x, int p, int n) { return (x >> (p + 1 - n)) & ~(~0 << n); } 输出为: getbits(63892(f994),4,3)=5(5) 我得到了其中的一部分,但在“大局”方面遇到了麻烦,主要是因为我不明白其中的一些细节(并非双关语
unsigned int getbits(unsigned int x, int p, int n) {
return (x >> (p + 1 - n)) & ~(~0 << n);
}
输出为:
getbits(63892(f994),4,3)=5(5)
我得到了其中的一部分,但在“大局”方面遇到了麻烦,主要是因为我不明白其中的一些细节(并非双关语)
我特别关注的是补码部分:
~(~0让我们使用16位作为示例。在这种情况下,~0
等于
1111111111111111
当我们左移此n
位(在您的情况下为3位)时,我们得到:
因为左侧的1
s被丢弃,右侧的0
s被输入。然后对其进行重新补充,得到:
0000000000000111
因此,这是一种聪明的方法,可以在数字的最低有效部分获得n
1位
您描述的“x位”已将给定的数字(f994=1111 1001 1001 0100
)向右移动足够远,以便最低有效的3位是您想要的。在本例中,您请求的输入位在那里,所有其他输入位都标记为,因为它们对最终结果不重要:
ff94 ...........101.. # original number
>> p+1-n [2] .............101 # shift desired bits to right
& ~(~0 << n) [7] 0000000000000101 # clear all the other (left) bits
ff94……….101.#原始编号
>>p+1-n[2]……101#将所需位右移
&~0使用以下示例:
INTX=0xF994,p=4,n=3;
intz=getbits(x,p,n)
并将重点放在这一系列操作上
(~0~)我认为最好的办法是手工解决问题,这样你就会明白它是如何工作的
下面是我使用8位无符号整数所做的
我们的数字是75,我们想要从位置6开始的4位。
函数的调用是getbits(75,6,4)
二进制中的75是0100 1011
因此,我们创建一个4位长的掩码,从最低阶位开始,就是这样做的
~0=1111111
300001001
现在我们有了一个低阶正确位数的掩码,以及我们想要的低阶原始位数的位数
所以我们&他们
0000 1001
& 0000 1111
============
0000 1001
所以答案是十进制9
注意:高阶半字节恰好是全零,这使得掩蔽在本例中是多余的,但它可能是任何东西,这取决于我们开始使用的数字的值。还没有人提到它,但在ANSI C~0中,在ANSI C~0>>中,n
会导致未定义的行为
//关于左移导致问题的帖子是错误的
无符号字符m,l
m=~0>>4;产生255,并且等于~0,但是
m=~0;
l=m>>4;产生的正确值15与:
m=255>>4
左移负数~0@jim:嘿,这不会影响你文章的准确性。内容方面比其他两种方式都要复杂,最好使用代码块和对齐更改。文章使用wiki标记,并在“?”上添加一个tute页面链接答案框上方。我必须读两遍才能检查它。我本打算建议右移,以保存指令,但我猜,~(~0我不懂什么,哪里错了?int a=0;所以printf(“%d”,a)给出0。现在,a=~a所以printf(“%d”,a)给出-1,为什么?@Anatoly:这是因为~
将所有位反转为1,在两个补码编码中,这是-1。回答得很好。我终于理解了这个例子!:)
0000000000000111
ff94 ...........101.. # original number
>> p+1-n [2] .............101 # shift desired bits to right
& ~(~0 << n) [7] 0000000000000101 # clear all the other (left) bits
0
0000000000000000
~0
1111111111111111
~0 << 4
1111111111110000
~(~0 << 4)
0000000000001111
0000 1001
& 0000 1111
============
0000 1001