C语言位运算
2017-05-02 15:06
225 查看
/* Get most significant byte from x */ int get_msb(int x) { /* Shift by w-8 */ int shift_val = (sizeof(int)-1)<<3; /* Arithmetic shift */ int xright = x >> shift_val; /* Zero all but LSB */ return xright & 0xFF; }
这个函数的功能是取 x 的最高有效位,即二进制表示中的高8位,全部用位运算来实现。
首先,确定要移动 x 的位数(x 为 int 型,长度为4字节,每字节8位,共32位),
int shift_val = (sizeof(int)-1)<<3;这里定义变量
shift_val为移动 x 的位数,赋值为24,因为 x 的二进制表示中最高位为前8位,我们的目标就是取前8位,后24位都是没用的。这个 24 是怎么计算来的呢?我们先计算出 int 型变量的字节长度,即
sizeof(int),再减一,因为我们需要最高位,不要剩下的部分,也就是只要一位,其他的不要。这时的结果是 3 ,然后对 3 进行移位运算,左移 3 位,相当于乘以 2 的 3 次方,即 3*8=24。为什么要对3进行移位运算,还要移动 3 位呢?因为这个 3 相当于 x 除最高位以外的字节,而最后操作 x 是要以位为单位的,一个字节为 8 位,3 个字节就要 3*8,这里我们全部用移位运算来实现,而我们知道,一个数左移一位就相当于乘以 2 ,所以乘以 8 就需要左移 3 位啦!
int xright = x >> shift_val;这一句意思就很明白了,上面我们计算出
shift_val = 24,所以这里就是对 x 右移 24 位,这样子 x 的后 24 位都被移除掉了,原来的高 8 位此时处于低 8 位,至于其他部分的值是什么,这要看系统了,一般情况下,x 是非负数,移位后,高位会补 0 ,x 是负数,移位后,高位会补 1。假设原来的 x 为 0011 1111 1111 1111 1111 1111 1111 1111,那么,x 右移 24 位后就变成了 0000 0000 0000 0000 0000 0000 0011 1111,这样子明白了吗?把计算后的新值赋给 xright。
return xright & 0xFF;这里的返回值为什么要和 0xFF 进行一次与运算呢?
我们知道,0xFF 的二进制形式为 0000 0000 0000 0000 0000 0000 1111 1111,也就是说,0xFF 的低 8 位全为 1,其他位全为 0。而与运算中,任何数和 1 相与都为它本身,和 0 相与都为 0 。所以,一个数如果和 0xFF 进行与运算后,得到的结果中就只会保留原数值的低 8 位,其他位全部变成 0 。而我们需要的刚好是 xright 的低 8 位,不想要它的其他部分(因为有可能 xright 的其他位并不是 0),因此,需要和 0xFF 进行一次与运算。