位运算符 #
一、位运算符概述 #
C#提供了以下位运算符:
| 运算符 | 名称 | 说明 |
|---|---|---|
| & | 按位与 | 两位都为1时结果为1 |
| | | 按位或 | 至少一位为1时结果为1 |
| ^ | 按位异或 | 两位不同时结果为1 |
| ~ | 按位取反 | 0变1,1变0 |
| << | 左移 | 各位左移若干位 |
| >> | 右移 | 各位右移若干位 |
| >>> | 无符号右移 | 无符号右移(C# 11+) |
二、按位与运算 #
2.1 基本用法 #
csharp
int a = 12;
int b = 10;
int result = a & b;
Console.WriteLine($"{a} = {Convert.ToString(a, 2).PadLeft(8, '0')}");
Console.WriteLine($"{b} = {Convert.ToString(b, 2).PadLeft(8, '0')}");
Console.WriteLine($"{result} = {Convert.ToString(result, 2).PadLeft(8, '0')}");
运算过程:
text
00001100 (12)
& 00001010 (10)
----------
00001000 (8)
2.2 应用场景 #
掩码操作:
csharp
int flags = 0b1101;
int mask = 0b0100;
bool hasFlag = (flags & mask) != 0;
int clearBit = flags & ~mask;
提取位:
csharp
int value = 0b10110110;
int lowNibble = value & 0x0F;
int highNibble = (value >> 4) & 0x0F;
判断奇偶:
csharp
bool isOdd = (number & 1) == 1;
bool isEven = (number & 1) == 0;
三、按位或运算 #
3.1 基本用法 #
csharp
int a = 12;
int b = 10;
int result = a | b;
Console.WriteLine($"{a} = {Convert.ToString(a, 2).PadLeft(8, '0')}");
Console.WriteLine($"{b} = {Convert.ToString(b, 2).PadLeft(8, '0')}");
Console.WriteLine($"{result} = {Convert.ToString(result, 2).PadLeft(8, '0')}");
运算过程:
text
00001100 (12)
| 00001010 (10)
----------
00001110 (14)
3.2 应用场景 #
设置标志位:
csharp
[Flags]
public enum Permissions
{
None = 0,
Read = 1,
Write = 2,
Execute = 4,
All = Read | Write | Execute
}
Permissions userPerms = Permissions.Read | Permissions.Write;
合并值:
csharp
byte red = 255;
byte green = 128;
byte blue = 64;
int rgb = (red << 16) | (green << 8) | blue;
四、按位异或运算 #
4.1 基本用法 #
csharp
int a = 12;
int b = 10;
int result = a ^ b;
Console.WriteLine($"{a} = {Convert.ToString(a, 2).PadLeft(8, '0')}");
Console.WriteLine($"{b} = {Convert.ToString(b, 2).PadLeft(8, '0')}");
Console.WriteLine($"{result} = {Convert.ToString(result, 2).PadLeft(8, '0')}");
运算过程:
text
00001100 (12)
^ 00001010 (10)
----------
00000110 (6)
4.2 应用场景 #
交换两个数:
csharp
int a = 10;
int b = 20;
a = a ^ b;
b = a ^ b;
a = a ^ b;
Console.WriteLine($"a = {a}, b = {b}");
简单加密:
csharp
string message = "Hello";
int key = 42;
string encrypted = new string(message.Select(c => (char)(c ^ key)).ToArray());
string decrypted = new string(encrypted.Select(c => (char)(c ^ key)).ToArray());
切换位:
csharp
int flags = 0b1010;
int toggleMask = 0b0100;
flags = flags ^ toggleMask;
五、按位取反运算 #
5.1 基本用法 #
csharp
int a = 12;
int result = ~a;
Console.WriteLine($"{a} = {Convert.ToString(a, 2).PadLeft(32, '0')}");
Console.WriteLine($"{result} = {Convert.ToString(result, 2).PadLeft(32, '0')}");
运算过程:
text
~ 00000000000000000000000000001100 (12)
-----------------------------------
11111111111111111111111111110011 (-13)
5.2 应用场景 #
清除位:
csharp
int value = 0b1111;
int mask = 0b0010;
int result = value & ~mask;
六、移位运算 #
6.1 左移运算 << #
csharp
int a = 5;
int result = a << 2;
Console.WriteLine($"{a} = {Convert.ToString(a, 2).PadLeft(8, '0')}");
Console.WriteLine($"{result} = {Convert.ToString(result, 2).PadLeft(8, '0')}");
运算过程:
text
00000101 (5)
<<
00010100 (20)
快速乘法:
csharp
int a = 5;
int multiplied = a << 1;
int multiplied4 = a << 2;
int multiplied8 = a << 3;
6.2 右移运算 >> #
csharp
int a = 20;
int result = a >> 2;
Console.WriteLine($"{a} = {Convert.ToString(a, 2).PadLeft(8, '0')}");
Console.WriteLine($"{result} = {Convert.ToString(result, 2).PadLeft(8, '0')}");
运算过程:
text
00010100 (20)
>>
00000101 (5)
快速除法:
csharp
int a = 20;
int divided = a >> 1;
int divided4 = a >> 2;
int divided8 = a >> 3;
算术右移(保留符号位):
csharp
int negative = -20;
int result = negative >> 2;
6.3 无符号右移 >>>(C# 11+) #
csharp
int negative = -20;
int result = negative >>> 2;
七、位标志枚举 #
7.1 定义标志枚举 #
csharp
[Flags]
public enum FileAccess
{
None = 0,
Read = 1,
Write = 2,
ReadWrite = Read | Write,
Delete = 4,
All = Read | Write | Delete
}
7.2 使用标志枚举 #
csharp
FileAccess access = FileAccess.Read | FileAccess.Write;
bool canRead = access.HasFlag(FileAccess.Read);
bool canDelete = (access & FileAccess.Delete) == FileAccess.Delete;
access |= FileAccess.Delete;
access &= ~FileAccess.Write;
access ^= FileAccess.Read;
八、实战示例 #
8.1 颜色处理 #
csharp
public struct Color
{
public byte A { get; set; }
public byte R { get; set; }
public byte G { get; set; }
public byte B { get; set; }
public int ToArgb()
{
return (A << 24) | (R << 16) | (G << 8) | B;
}
public static Color FromArgb(int argb)
{
return new Color
{
A = (byte)((argb >> 24) & 0xFF),
R = (byte)((argb >> 16) & 0xFF),
G = (byte)((argb >> 8) & 0xFF),
B = (byte)(argb & 0xFF)
};
}
}
8.2 位图操作 #
csharp
public class BitArray
{
private int[] _data;
public BitArray(int size)
{
_data = new int[(size + 31) / 32];
}
public bool this[int index]
{
get => (_data[index / 32] & (1 << (index % 32))) != 0;
set
{
if (value)
_data[index / 32] |= 1 << (index % 32);
else
_data[index / 32] &= ~(1 << (index % 32));
}
}
}
8.3 权限管理 #
csharp
[Flags]
public enum Permission
{
None = 0,
Create = 1,
Read = 2,
Update = 4,
Delete = 8,
All = Create | Read | Update | Delete
}
public class User
{
public Permission Permissions { get; set; }
public bool Can(Permission permission)
{
return Permissions.HasFlag(permission);
}
public void Grant(Permission permission)
{
Permissions |= permission;
}
public void Revoke(Permission permission)
{
Permissions &= ~permission;
}
}
九、位运算技巧 #
9.1 判断2的幂 #
csharp
bool IsPowerOfTwo(int n)
{
return n > 0 && (n & (n - 1)) == 0;
}
9.2 计算绝对值 #
csharp
int Abs(int n)
{
int mask = n >> 31;
return (n + mask) ^ mask;
}
9.3 交换符号 #
csharp
int Negate(int n)
{
return ~n + 1;
}
9.4 计算位数 #
csharp
int CountBits(int n)
{
int count = 0;
while (n != 0)
{
count += n & 1;
n >>= 1;
}
return count;
}
十、总结 #
位运算符要点:
| 运算符 | 说明 |
|---|---|
| & | 按位与 |
| | | 按位或 |
| ^ | 按位异或 |
| ~ | 按位取反 |
| << | 左移 |
| >> | 右移 |
下一步,让我们学习赋值运算符!
最后更新:2026-03-26