常用位操作以及相关原理

& 运算:1 & 1 = 1,其他都为0(有0即为0)

|  运算: 0 | 0  = 0 ,其他都为1(有1即为1)

^ 运算 : 0 ^ 0 = 0, 1 ^ 1 = 0 (相同数字^为0,不同数字^为1)

~运算: ~1001 = 0110 ( 将所有位取反,也叫取反运算)

1.判断给定数字的奇偶性

if((x & 1) = 1)
    x is 奇
else
    x is 偶

判断一个数是否奇偶,只要判断该数二进制的最后一位是否为1即可。如下

//判断数字9是否为奇数
    00001001
    00000001    (1的二进制)
&   --------
    00000001

最后得出数字与1进行&运算后,结果为1为奇数,为0为偶数。

2.测试给定数字的第n位是否是1

if (x & (1 << n) == 0)
    x的第n位是0
else
    x的第n位是1

此用法与上面的大同小异,只是将1左移对应的n位,通过&运算来判断该位置是否为1。

//判断125的第3位是否为1
125 & (1 << 3)

125    1111101
1<<3   0001000
 &     -------
       0001000    (8)

结果为8,不为0,因此125第三位为1.

3.将给定数字x的第n位置为1

x | (1 << n)

由于|运算的特性,所以我们可以用来置1,如下将125第2位置1

//将指定数字125第2位置为1
125 | (1 << 2)

125    1111101
1<<2   0000010
 |     -------
       1111111    (127)

4.将给定数字x的第n位置0

y = x & ~(1 << n)

~(1 << n) 将除了第n位的其他位置为1,n位置为0.

//将指定数字125的第3位置为0
125 & ~(1 << 3)

125        1111101
~(1<<3)    1110111
  &        -------
           1110101    (117) 

5.将给定数字第n位反转(0变为1,1变为0)

x ^ (1 << n)

来看个具体例子

// 将数字125的第4位反转
125 ^ (1 << 4)

125    1111101
1<<4   0010000
  ^    -------
       1101101    (109)
// 将数字109的第4位反转
109 ^ (1 << 4)

109    1101101
1<<4   0010000
  ^    -------
       1111101    (125)

6.将给定数字的最右边的1置为0

y = x & (x - 1)
//将125最右边的1置为0
125 & (125 - 1)

125    1111101
124    1111100
 &     -------
       1111100

为什么x & (x-1)会达到这种效果呢?

其实我们只要明白了二进制四则运算原理就简单了。二进制减法中会进行有借位一说,如0-1=1,其实是0向前借一位变为10(10在二进制中为2),再减1得到1;所以我们x-1就是x从最右边开始如果为0变为1,碰到1变为0并停止(10010->10001;10011->10010),因此将两个数进行&运算将会得到x最右边1变为0的结果。

7.除了最右边的1,其他置为0

这个其实正好与上面相反,先将x-1取反,在进行&运算

//取反再&
x & ~(x - 1)
x & (-x)

~(x - 1) =====》 -x

//对于~10,在计算机中存储为
11111111 11111111 11111111 11110101   (这是10取反的结果,但却是未知数X的补码形式)
//先取反,得
00000000 00000000 00000000 00001010   (此处,再次取反,返回10)
//再加1,得
00000000 00000000 00000000 00001011   (10+1得11)
//最高位变1,即
10000000 00000000 00000000 00001011   (取相反数即-11)
//看出规律
~x = -(x + 1)
-x = ~(x - 1)

8.将最右边的1的右边位置 置为1

//这里只要明白|运算的规则就简单了
x | (x - 1)

x-1会将最右边1置为0,并将此1后面的0置为1,此1之前的不变,再进行&运算就完成了。

9.将最右边0置为1,其他位置为0

//其实与第7点类似
~x & (x + 1)

这个我们首先明白x+1做了什么操作---》二进制+运算会将最右边的0置为1,并将此0右边的1置为0(1000101+1=1000110);

再思考我们如果想将所有位置0,必须与自身相反的数取&,因此最后得出结论:只要有拿到x的最右边的0置为1的数,与~x取&,就大功告成了。O(∩_∩)O~

10.将最右边的0置1

//其实与上面第8点类似
x | (x + 1)

有了上面的基础,这个就异常简单了,只要把最右边0置为1,那就是+1操作,进行|运算就OK了。

综上所述,我们想0置1,就进行+运算;想1置0,就进行-运算。

位操作的世界方才窥得一点,道阻且长,只能上下求索啦!

如有错误,欢迎大家指正

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值