一点点位运算
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)