概念
- 反码:原值取反后的值,成为原值的反码。
- 补码:原值的反码再+ 1
- 负数用补码表示
- -1 的二进制全是 1111111
- 5 = 101(前缀全是 0)
- -5 = 011(前缀全是 1)
位的功能操作
功能 | 操作 |
---|---|
除 2 | >> |
乘 2 | << |
正负符号变换 | 取反再+1 |
从 a 中消去 b 中的 1 | a &= ~b(和 b 的反,做&运算) |
取最右的 1 | n & -n |
删最右的 1 | x & x-1 |
n |= n >> 1; n |= n >> 2; n |= n >> 4; | 第一个 1 右侧的 bit 置为 1 |
Java 位运算符
符号 | 描述 | 运算规则 |
---|---|---|
& | 与 | 两个位都为 1 时,结果才为 1 |
| | 或 | 两个位都为 0 时,结果才为 0 |
^ | 异或 | 两个位相同为 0,相异为 1 |
~ | 取反 | 0 变 1,1 变 0 |
<< | 左移 | 高位丢弃,低位补 0 |
>> | 右移 | 无符号数高位补 0;有符号数编译器有的补符号位,有的补 0 |
>>> | 无符号右移 | Java 运算,高位补 0 |
例题
一堆数字中,有 2 个数字各出现一次,其它都出现两次。Leetcode
解题重点:
- one ^ two = xor
- xor & -xor => one 和 two 的第一个差异位
- 用差异位可以辨别一个数字可能是 one 还是 two