位运算操作符
左移操作符
num << i;将num向左移动i位
左移:左边丢一个,右边补0
- 这里实际的num没变,移动完的结果变了
- 左移一位,有*2的效果
右移操作符
- 逻辑右移
左边填0,右边丢掉 - 算术右移(most)
左边符号填充,正0负1,右边丢掉 - -1的补码全是1
- 对于正数有/2的效果
左乘右除
不能移动负数位
按位与
a&b
全1则1,有0则0
按位或
a | b
全0则0,有1则1
按位异或
a ^ b
相同为0,相异为1
按位取反
~a 单目操作符
如果取完是正数,就不用动
位运算的应用
按位与
** 判断奇偶数 **
- 普通的方法:取模运算,要注意正负数,多讨论一种情况
- 偶数最低二进制位是0
- 奇数最低二进制位是1
- 将一个数按位与上1,就获得了最后一个数
- 为1是奇数,为2是偶数
** 保留二进制位中的指定位 **
- 给一个数字m的二进制为,想留哪个数就把那一位设置为1,其余的为0,让m与那个数字按位与
** 获得第i位 **
- 只需将那个数向右移动i位(要得到的i就在最后一位)
-
- 再按位与1
- (x>>i) &1
== 获得一个数,就给他右移再按位与 ==
** 将二进制位中最右边的1变为0 **
x &(x-1)
- 可以用于求一个数二进制序列中有几个1
** 只保留二进制位最右边的1 **
x & -x
应用:快速查找最右边的1
按位或
** 将指定二进制位设置为一 ** 其余不变
给一个数字m的二进制位,要制定哪几(一)位就把m的那几位设置为1,其余为0,再按位或
- x |= m
- 如果只设置其中一位,就 1<<i, 再与x按位或
** 将指定二进制位设置为0 **
要设置哪位,就把m的第i位设置为0,其余不变
x &= ~(1<<i)
按位异或
** 反转指定二进制位 **
x^(1<< i)
异或的巧用
1.两个相同的数字异或结果是0
x ^ x = 0;
2.0和任何数字异或结果还是0
3.支持交换律
a ^ b ^ a = a ^a ^ b = 0 ^ b = b;
- 交换两个整数的值
- 创建临时变量tmp
- a = a^b
b = a^b 只适用于整数
a = a^b
- 找出单身狗
Q:其余数字都出现两次,找出那个只出现了一次的数字
ans:把所有数字异或在一起,最后等于谁谁就是落单的 - 丢失的数字
- 把该放的数字异或在一起,再把数组的数字异或在一起,再总共异或在一起
- 宗旨:两两配对