您的位置:首页 > 编程语言 > C语言/C++

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 进行一次与运算。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息