掌握 C# 位运算与移位运算符:全面指南
C# 位运算与移位运算符
本教程详细讲解 C# 中的位运算与移位运算符。C# 提供 4 个位运算符和 2 个移位运算符,用于对整数和布尔数据进行位级操作。
位运算和移位运算符用于在整数(int、long 等)和布尔数据上执行位级操作。这些运算符在日常开发中不常用,但了解它们有助于编写高性能、底层逻辑的代码。
若想探索实际应用场景,可参考 位运算的实际应用。
C# 中可用的位运算与移位运算符如下:
| 运算符 | 名称 |
|---|---|
| ~ | 按位取反 |
| & | 按位与 |
| | | 按位或 |
| ^ | 按位异或 |
| << | 左移 |
| >> | 右移 |
按位或运算符 (|)
按位或运算符用 | 表示。它对两个操作数的对应位执行或操作:若任一位为 1,结果位为 1,否则为 0。
若操作数为 bool 类型,按位或等同于逻辑或操作。
示例:
14 = 00001110 (二进制) 11 = 00001011 (二进制)
14 与 11 的按位或运算:
00001110 00001011 -------- 00001111 = 15 (十进制)
示例 1:按位或
using System;
namespace Operator {
class BitWiseOR {
public static void Main(string[] args) {
int firstNumber = 14, secondNumber = 11, result;
result = firstNumber | secondNumber;
Console.WriteLine("{0} | {1} = {2}", firstNumber, secondNumber, result);
}
}
}
输出:
14 | 11 = 15
按位与运算符 (&)
按位与运算符用 & 表示。对应位全为 1 时结果才为 1,否则为 0。
布尔操作数时等同于逻辑与。
示例:
14 = 00001110 11 = 00001011
按位与运算:
00001110 00001011 -------- 00001010 = 10 (十进制)
示例 2:按位与
using System;
namespace Operator {
class BitWiseAND {
public static void Main(string[] args) {
int firstNumber = 14, secondNumber = 11, result;
result = firstNumber & secondNumber;
Console.WriteLine("{0} & {1} = {2}", firstNumber, secondNumber, result);
}
}
}
输出:
14 & 11 = 10
按位异或运算符 (^)
按位异或用 ^ 表示。对应位相同则结果为 0,不同则为 1。
布尔操作数时等同于逻辑异或。
示例:
14 = 00001110 11 = 00001011
按位异或运算:
00001110 00001011 -------- 00000101 = 5 (十进制)
想深入了解异或的妙用,可参考 XOR 的魔力。
示例 3:按位异或
using System;
namespace Operator {
class BitWiseXOR {
public static void Main(string[] args) {
int firstNumber = 14, secondNumber = 11, result;
result = firstNumber ^ secondNumber;
Console.WriteLine("{0} ^ {1} = {2}", firstNumber, secondNumber, result);
}
}
}
输出:
14 ^ 11 = 5
按位取反运算符 (~)
按位取反用 ~ 表示,是一元运算符,仅作用于一个操作数。它将每一位取反:0 变 1,1 变 0。
示例:
26 = 00011010 (二进制)
26 的按位取反:
~ 00011010 = 11100101 = 229 (十进制)
示例 4:按位取反
using System;
namespace Operator {
class BitWiseComplement {
public static void Main(string[] args) {
int number = 26, result;
result = ~number;
Console.WriteLine("~{0} = {1}", number, result);
}
}
}
输出:
~26 = -27
得到 -27 而非预期的 229。**这是为什么?**
因为二进制 11100101 在计算机中以补码形式表示 -27。负数采用补码存储。
对于任意整数 n,其补码为 -(n+1)。
| 十进制 | 二进制 | 补码值 |
|---|---|---|
| 0 | 00000000 | -(11111111 + 1) = -0 |
| 1 | 00000001 | -(11111110 + 1) = -256 |
| 229 | 11100101 | -(00011010 + 1) = -27 |
补码运算中溢出位被忽略。26 的按位取反为 229,而 229 的补码即 -27,故输出 -27。
左移运算符 (<<)
左移运算符 << 将数值向左移动指定位数,低位补 0。
十进制上等价于:
num * 2^bits
示例:
42 = 101010 (二进制)
左移操作:
42 << 1 = 84 (二进制 1010100) 42 << 2 = 168 (二进制 10101000) 42 << 4 = 672 (二进制 1010100000)
示例 5:左移
using System;
namespace Operator {
class LeftShift {
public static void Main(string[] args) {
int number = 42;
Console.WriteLine("{0}<<1 = {1}", number, number << 1);
Console.WriteLine("{0}<<2 = {1}", number, number << 2);
Console.WriteLine("{0}<<4 = {1}", number, number << 4);
}
}
}
输出:
42<<1 = 84 42<<2 = 168 42<<4 = 672
右移运算符 (>>)
右移运算符 >> 将数值向右移动指定位数。对于有符号整数,高位用符号位填充(算术右移)。
十进制上等价于:
floor(num / 2^bits)
示例:
42 = 101010 (二进制)
右移操作:
42 >> 1 = 21 (二进制 010101) 42 >> 2 = 10 (二进制 001010) 42 >> 4 = 2 (二进制 000010)
示例 6:右移
using System;
namespace Operator {
class RightShift {
public static void Main(string[] args) {
int number = 42;
Console.WriteLine("{0}>>1 = {1}", number, number >> 1);
Console.WriteLine("{0}>>2 = {1}", number, number >> 2);
Console.WriteLine("{0}>>4 = {1}", number, number >> 4);
}
}
}
输出:
42>>1 = 21 42>>2 = 10 42>>4 = 2
C语言