一点点位运算

2015-04-04

位运算操作某种程度上可以看出一点基本功,区分懂底层和不懂的人。

先做个题

现在假设有一个uint32,高16位是mask位,低16位是value位。这样,修改可以用一个uint32的值表示。

比如说,我用一个uint32的变量存一些状态位(其实只有低16位有效),这个变量叫status。用另一个uint32变量存修改,这个变量叫change。

status = 0x 00 00 00 02
change = 0x 00 09 00 01

意思是,对status进行修改,要把最后一位设置为1,把倒数第四位设置为0,如何执行这个位操作?

只使用到了4位,写简单一点,把change拆成mask和value来看:

status = 0010
mask   = 1001
value  = 0001

第一步,status不在mask中的位是需要保留的,我们将它拿出来,通过对mask取反,再跟status做与运算:

tmp1 = ~mask
tmp2 = status & tmp1

第二步,status中mask对应的位是需要更新的为value的,我们将需要的更新从value中拿出来:

tmp3 = value & mask

第三步,将上面的两个结果合并,得到最终结果

status = tmp1 | tmp2

ok.

这里是以4位来说明的,最初那个问题的也可以解出来了,要做一些移位,就不写了。也许用异或运算做还有更简单的方法。

基本

或运算用于置位,将第5位置为1:

x | (1<<5)

与运算用于清位,将第5位清0:

x &= ~(1<<5)

进阶

判断一个数是否8的倍数(低3位全0):

x & (1<<3) == 0

将一个数按8的倍数向上取整:

x = (x+1) & (1<<3)

判断一个数是否2的n次方,如2,4,8,16,32,64...:

x & (x-1) == 0

来个高端的

将一个32位的数,按位对称的反转,见这里

玩得开心!

--------------2015.6.23更新-------------

再来一个判断一个机器是32位还是64位的方法:

(^0)>>63 如果等于1,说明是64位,如果等于0,说明是32位(假设现在机器不是64就是32)。

指针的占的大小可以用4 << ((^0)>>63)

面试题位运算