取一个数从右边第 p 位开始向右数 n 位的字段理解
《C 程序设计语言》p39 底部 getbits 函数代码理解
/* getbits函数:返回x中从第p位开始的n位 */
unsigned getbits(unsigned x, int p, int n)
{
return (x >> (p+1-n)) & ~(~0 << n);
}
在这段函数中,x 为无符号整型操作数,可以通过举例子来理解函数中的位运算为什么拿到了第 p 位开始的 n 位。
假设 x 为 40, 即 0010 1000
我们要取第 4 位开始的 3 位,即 getbits(40, 4, 3)
直接看,我们很快就能知道要取的就是从右边数第 4 位后的三个 即 010
首先地一个操作 x >> (p+1-n)
的目的就是为了让那三位顶到最右边,这里 p + 1
是因为这里假定最右边的第一位是第 0 位,这样向右位移的两位就是
0000 1010
那么之后我们又如何知道要得就是这三位呢?
前提就是让这三位左边的数都为 0 即可,这时就可以想到另外一个为运算符 &
按位与
按位与只有在两个数都为 1 的时候才会是 1,所以我们只需要有这样一个二进制数
0000 0111
就可以让右三位该是几就是几,而其他的必定是 0。也就是说我们只需要写一个能得到这个二进制数的表达式即可,便是上述代码中的
~(~0 << n)
首先让 0 都变成 1 ~0
=> 1111 1111
随后向左位移要取的位数,低位补 0 ~0 << 3
=> 1111 1000
然后再进行一次取反就得到了0000 0111
接下来只需要跟之前顶到最右的那三位进行按位与操作就能让
0000 1010
=> 0000 0010
这样就拿到了 x 中从第 4 位开始的 3 位