二进制表示
从现代计算机中所有的数据二进制的形式存储在设备中。即 0、1 两种状态。
例如 用8位存储
1 | 0: 00000000 |
可以使用如下公式 f(a) = 2^(x-1) x为位数
位运算
从现代计算机中所有的数据二进制的形式存储在设备中。即 0、1 两种状态,计算机对二进制数据进行的运算(+、-、*、/)都是叫位运算,即将符号位共同参与运算的运算。
1 | a := 3 |
计算两个数的和,因为在计算机中都是以二进制来进行运算,所以上面我们所给的 int 变量会在机器内部先转换为二进制在进行相加
1 | 3: 0 0 0 0 0 0 1 1 |
可以如下表示
1 | 3 = 2^1 + 2^0 |
位运算符
位运算符对整数在内存中的二进制位进行操作
运算符 | 描述 |
---|---|
& | 参与运算的两数各对应的二进位相与。 (两位均为1才为1) |
^ | 参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。 (两位不一样则为1) |
<< | 左移n位就是乘以2的n次方。 “a<<b”是把a的各二进位全部左移b位,高位丢弃,低位补0。 |
>> | 右移n位就是除以2的n次方。 “a>>b”是把a的各二进位全部右移b位。 |
&^ | 位与非,AND NOT |
与运算 &
参与运算的两数各对应的二进位相与。就是2为都为1 则结果为1,有一位为0,结果都为0
运算符为**&**
1 | a := 1 # 00000001 |
参与运算的两数各对应的二进位相或。 (两位有一个为1就为1)
运算符为 |
1 | a := 1 # 00000001 |
异或 ^
参与运算的两数各对应的二进位相异或,也就是当两对应的二进位相异时,结果为1
运算符为^
1 | a := 1 # 00000001 |
<< 和 >> 运算符
1 | a << n; 将 a 中的所有位向左偏移 n 次 |
1 | var a int8 = 3 |
&^ 运算符
&^ 运算符叫做 AND NOT。它是一个 使用 AND 后,再使用 NOT 操作的简写。该操作符定义如下:
a 与b的负数相与
1 | Given operands a,b |
它有一个有意思的特性:如果第二个操作符返回 1。那么该位将会被清 0
1 | AND_NOT(a, 1) = 0; clears a |
相关应用
测试第 n 位是不是指定的值
1 << n位,然后&运算
1 | var a int8 = 12 |
计算一个数 *4
数左移2位
1 | var a int8 = 12 |
去除后4位
使用 AND NOT (&^)操作符来清掉 a 的后 4 位
1 | ar a byte = 0x1A |
或者 注意 0x0F与0xF0区别
补数
求数字的补数https://leetcode.cn/problems/number-complement/
1 | 476. 数字的补数 |
题解 这里用到异或^
1 | func findComplement(num int) int { |
汉明距离
求461. 汉明距离 https://leetcode.cn/problems/hamming-distance/
1 | 461. 汉明距离 |
题解,使用异或^ 然后计算1的个数
1 | func hammingDistance(x int, y int) int { |