位运算知识点总结

概述

任何一台计算机内部保存的是二进制,再进行逻辑运算和算术运算的时候,计算机只会对二进制执行运算,而计算机对二进制执行的运算叫做位运算。

举例说明,计算机执行3 + 5是如何计算的。

3: 0 0 0 0 0 0 1 1

5: 0 0 0 0 0 1 0 1

8: 0 0 0 0 1 0 0 0

就这样讲十进制转换成二进制后,执行简单的0,1计算,我们平时再写代码的时候常用的运算符为(+,-,*,/,%),但是如何我们能合理的使用位运算,将很大程度上提高我们代码执行的效率。

位运算符

符号名称作用
&都为1,才为1
|有一个1,都可以为1
^异或相同为0,不同为1
~取反1变为0,0变为1
<<左移所有位向左移动若干位,高位溢出丢弃,低位补0
>>右移所有位向左移动若干位,分有符号位和无符号位

按位与(&)

先看与运算逻辑:

1 & 1 = 1, 1 & 0 = 0, 0 & 1= 0, 0 & 0 = 0

当第一个数为0时,此时形成断路,剩下的表达式不会执行,程序就会输出0

input: 2 & 2

output: 2

input: 2 & 0

output: 0

总结规律:

  1. 任何一个数与其本身与为其本身,与0与为0

  2. 另外通过与运算,我们可以知道一个数是否是奇数还是偶数。

    奇数 & 1 = 1

    偶数 & 1 = 0

按位或(|)

运算逻辑:

1 | 1 = 1,1 | 0 = 1,0 | 1 = 1,0 | 0 = 0

注意:负数的或运算按它的补码进行运算(负数的补码 = 原码取反 + 1)

按位异或(^)

运算逻辑:

1 ^ 1 = 0,1 ^ 0 = 1, 0 ^ 1 = 1, 0 ^ 0 = 0

总结:

  1. 参加运算的两个数相同的话为0
  2. 任何一个数与0进行异或为其本身

异或满足以下几个性质:

  • 交换律:a ^ b = b ^ a
  • 结合律:a ^ (b ^ c) = (a ^ b) ^ c
  • 自反性:a ^ b ^ b = a ^ 0 = a
  • a ^ a = 0, a ^ 0 = a

同样,异或运算还能够交换两个数,再没有第三个数的情况下:

void swap(int& a, int &b)
{
	a ^= b;
	b ^= a;
	a ^= b;
}

按位取反

运算逻辑:

~1 = 0, ~0 = 1

如果我们再IDE中编译的话,我们会发现~1 = -2, ~0 = -1。

what?这是怎么一回事,不是取反嘛,怎么会成这种结果。

其实上面的结果并没有错,我们一步一步来看。

我们假设都为八位二进制。

1: 0000 0001

取反的结果为:1111 1110,此时这个数为负数是以补码的形式保存在计算机内部中的,我们取它的原码为:1000 0010,最高位为符号位,此时为负。

所以最终结果为-2。

我们在来看负数如何取反,

例如:~-2 = 1是如何得来得

要知道计算机保存负数是保存的它的补码。

-2 :1000 0010

补码:1111 1110

此时再取反:0000 0001此时为正数

取原码:0000 0001(正数的补码=原码),所以最终结果为1

说到这,我们再来说一下负数的补码怎么计算:

X补 = ~X原 + 1 (原码取反加1,符号为不变)

正数的原码=反码=补码

左移(<<)

运算逻辑:

正数的左移,例如int32位正数,把每一位向左移动若干位,最左边的位丢弃若干位,最右边的补上若干0

负数的话,由于最高位是1,所以最高位保持不变,左边舍弃若干个,除了最高位,右边补若干个0即可

例如 a = 1000 0110(-6) a << 1 = 1000 11 00(-12)

其实我们可以发现,左移实际上就是 a * 2的左移多少位次方

右移(>>)

运算逻辑:

正数的右移若干位,只需要左边补上若干个0,右边舍弃若干个即可。

负数的右移若干位,只需左边不上若干个1,右边舍弃若干个。

5 >> 1 = 2

5 >> 2 = 1

右移多少位,相当于除于2的多少位次方。

不过需要注意的是,我们有些编程语言处理情况不一样。

在Java中,-3 >> 1 = -2, -3 / 2 = -1

但是在Python中,-3 >> 1 = -2, -3 // 2 = -2。

不过右移运算得出的答案都遵循计算机运算规则,但是除法的话是按照解释器的处理而言。

总结

位运算到此为止,我们再写代码的时候其实可以把某些运算写成位运算更能题高效率。

  1. 判断x的奇偶数

    x % 2 == 1 // 常规写法

    x & 1 == 1 // 为真奇数,为假偶数

  2. 计算中位数

    mid = (left + right) / 2 // 常规写法

    mid = (left + right) >> 1 // 位运算

  3. 交换两个数

    a ^= b

    b ^= a

    a ^= b

总结到此,欢迎补充

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值