位运算符对整数数据在单个比特级别执行操作。这些操作包括测试、设置或移位实际的比特。例如,
a & b
a | b
在示例中,&
和 |
是位运算符。
以下是 Swift 中包含的各种位运算符列表
按位 AND 运算符
按位 **AND** &
运算符仅当两个操作数都为 **1** 时才返回 **1**。否则,它返回 **0**。
a
和 b
的按位 **AND** 操作可以用下表表示
a | b | a & b |
---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
注意: 上表称为按位 AND 运算符的“真值表”。
让我们看一下整数 **12** 和 **25** 的按位 **AND** 操作
12 = 00001100 (In Binary)
25 = 00011001 (In Binary)
// Bitwise AND Operation of 12 and 25
00001100
& 00011001
_____________
00001000 = 8 (In Decimal)
示例 1:按位 AND 运算符
var a = 12
var b = 25
var result = a & b
print (result) // 8
在上面的示例中,我们声明了两个变量 a
和 b
。在这里,请注意这一行,
var result = a & b
在这里,我们正在执行 a
和 b
之间的按位 **AND** 操作。
按位 OR 运算符
按位 **OR** |
运算符只要至少有一个操作数为 **1**,就返回 **1**。否则,它返回 **0**。
a
和 b
的按位 **OR** 操作可以用下表表示
a | a | a | b |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 1 | 1 |
1 | 0 | 1 |
让我们看一下整数 **12** 和 **25** 的按位 **OR** 操作
12 = 00001100 (In Binary)
25 = 00011001 (In Binary)
Bitwise OR Operation of 12 and 25
00001100
| 00011001
____________
00011101 = 29 (In decimal)
示例 2:按位 OR 运算符
var a = 12
var b = 25
var result = a | b
print(result) // 29
在这里,我们正在执行 **12** 和 **25** 之间的按位 **OR** 操作。
按位 XOR 运算符
按位 **XOR** ^
运算符仅当其中一个操作数为 **1** 时才返回 **1**。但是,如果两个操作数都为 **0**,或者两个都为 **1**,则结果为 **0**。
a
和 b
的按位 **XOR** 操作可以用下表表示
a | b | a ^ b |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
让我们看一下整数 **12** 和 **25** 的按位 **XOR** 操作
12 = 00001100 (In Binary)
25 = 00011001 (In Binary)
Bitwise XOR Operation of 12 and 25
00001100
^ 00011001
____________
00010101 = 21 (In decimal)
示例 3:按位 XOR 运算符
var a = 12
var b = 25
var result = a ^ b
print(result) // 21
在这里,我们正在执行 **12** 和 **25** 之间的按位 **XOR** 操作。
按位 NOT 运算符
按位 **NOT** ~
运算符会反转比特(**0** 变为 **1**,**1** 变为 **0**)。

a
的按位 **NOT** 操作可以用下表表示
重要的是要注意,任何整数 **N** 的按位 NOT 等于 **-(N + 1)**。例如,
考虑整数 **35**。根据规则,**35** 的按位 NOT 应该是 **-(35 + 1)** = **-36**。现在,让我们看看我们是否能得到正确答案。
35 = 00100011 (In Binary)
// Using bitwise NOT operator
~ 00100011
________
11011100
在上面的示例中,**00100011** 的按位 NOT 是 **11011100**。在这里,如果我们转换为十进制,我们得到 **220**。
然而,需要注意的是,我们不能直接将结果转换为十进制并得到期望的输出。这是因为二进制结果 11011100
也等同于 -36。
要理解这一点,我们首先需要计算 **-36** 的二进制输出。我们使用 **2 的补码** 来计算负整数的二进制。
2 的补码
数字 **N** 的 **2 的补码** 给出 **-N**。它通过反转比特(**0** 变为 **1**,**1** 变为 **0**)然后加 **1** 来计算。例如,
36 = 00100100 (In Binary)
1's Complement = 11011011
2's Complement :
11011011
+ 1
________
11011100
在这里,我们可以看到 **36**(即 **-36**)的 **2 的补码** 是 **11011100**。此值等同于我们在上一节中计算的 **35** 的按位补码。
因此,我们可以说 **35** 的按位补码 = **-36**。
示例 4:按位 NOT 运算符
var b = 12
var result = ~b
print(result) // -13
在上面的示例中,我们对 **12** 执行了按位 **NOT** 操作。
The bitwise complement of 12 = - (12 + 1) = -13
i.e. ~12 = -13
这正是我们在输出中得到的结果。
左移运算符
左移运算符将所有比特向左移动指定的比特数。它用 <<
表示。

正如我们从上图所示,
- 我们有一个四位数。当我们对其执行 **1** 位左移操作时,每个比特都向左移动 **1** 位。
- 结果是,最左边的比特被丢弃,而最右边的比特保持空白。这个空白被 **0** 填充。
示例 5:左移运算符
var a = 3
var result = a << 2
print(result) // 12
在上面的示例中,我们创建了一个值为 3
的变量 a
。注意这一行
var result = a << 2
在这里,我们正在对 a
执行 **2** 位左移操作。
右移运算符
右移运算符将所有比特向右移动指定的比特数。它用 >>
表示。

正如我们从上图所示,
- 我们有一个四位数。当我们对其执行 **1 位** 右移操作时,每个比特都 **向右移动 1 位**。
- 结果是,最右边的比特被丢弃,而最左边的比特保持空白。对于 **无符号数**,这个空白被 **0** 填充。
- 对于 **有符号数**,符号位(**正数**为 **0**,**负数**为 **1**)用于填充空白的比特位。
注意:有符号整数表示正数和负数,而无符号整数仅表示正整数。
示例 5:右移运算符
var a = 4
var result = a >> 2
print(result) // 1
a = -4
result = a >> 2
print(result) // -1
在上面的示例中,我们对值 **4** 和 **-4** 执行 **2** 位右移操作。
正如您所看到的,**4** 和 **-4** 的结果不同。这是因为 **4** 是无符号整数,所以空白被 **0** 填充,而 **-4** 是负有符号数,所以空白被 **1** 填充。