C# 位运算和位移运算符
- 种类丰富的运算符:C# 提供了多种位运算符(如位取反
~
、位与&
、位或|
、位异或^
)和位移运算符(如位左移<<
和位右移>>
)。 - 运算的基础原理:这些运算符在整数的二进制级别上操作,例如位或和位与分别在相应位上执行逻辑或和逻辑与。
- 位移运算的效果:位左移
<<
相当于乘以 2 的幂次,而位右移>>
相当于除以 2 的幂次并 取整。
- 运算符种类:C# 提供了多种位运算和位移运算符,如位取反(
~
)、位与(&
)、位或(|
)、位异或(^
)、位左移(<<
)和位右移(>>
)。 - 位运算原理:位运算符在整数的二进制级别上操作,例如位或(
|
)和位与(&
)分别在相应位上执行逻辑或和逻辑与运算。 - 位移操作效果:位左移(
<<
)相当于乘以 2 的幂次,位右移(>>
)则相当于除以 2 的幂次,且结果取整。
位运算和位移运算符用于对整数(如 int、long 等)和布尔数据进行位级操作。这些运算符在实际情况中并不常用。
如果您有兴趣探索更多,请访问 位运算的实际应用。
C# 中可用的位运算和位移运算符列在下面。
C# 位运算符列表
运算符 | 运算符名称 |
---|---|
~ | 位取反 |
& | 位与 |
| | 位或 |
^ | 位异或 (XOR) |
<< | 位左移 |
>> | 位右移 |
位或
位或运算符由 |
表示。它对两个操作数的相应位执行位或运算。如果任一位是 1
,结果就是 1
。否则结果为 0
。
如果操作数的类型是 bool
,位或运算等价于它们之间的逻辑或运算。
例如,
14 = 00001110(二进制)
11 = 00001011(二进制)
14 和 11 之间的位 OR
运算:
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
位与
位与运算符由 &
表示。它对两个操作数的相应位执行位与运算。如果任一位是 0
,结果就是 0
。否则结果为 1
。
如果操作数的类型是 bool
,位与运算等价于它们之间的逻辑与运算。
例如,
14 = 00001110(二进制)
11 = 00001011(二进制)
14 和 11 之间的位与运算:
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
。
如果操作数的类型为 bool
,位异或运算等同于它们之间的逻辑异或运算。
例如,
14 = 00001110(二进制)
11 = 00001011(二进制)
14 和 11 之间的位异或操作:
00001110
00001011
--------
00000101 = 5(十进制)
如果你想了解更多关于位异或的使用,可以访问 The Magic of 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
位补码
位补码运算符由 ~
表示。它是一元运算符,即只对一个操作数操作。~
运算符反转每一位,即将 1 变为 0,将 0 变为 1。
例如,
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
当我们期望输出 229
时,为什么得到 -27
呢?
这是因为我们期望的二进制值 11100101
实际上是 -27
的二进制补码表示。在计算机中,负数用二进制补码表示。
对于任何整数 n,n 的二进制补码将是 -(n+1)
。
二进制补码
十进制 | 二进制 | 二进制补码 |
---|---|---|
0 | 00000000 | -(11111111 + 1) = -00000000 = -0(十进制) |
1 | 00000001 | -(11111110 + 1) = -11111111 = -256(十进制) |
229 | 11100101 | -(00011010 + 1) = -00011011 = -27 |
二进制补码中溢出值会被忽略。
26
的位取反是 229(十进制),而 229
的 2 进制补码是 -27
。因此输出是 -27
而不是 229
。
位左移
位左移运算符由 <<
表示。<<
运算符将数字向左移动指定位数。最不重要的位补零。
在十进制中,它相当于
num * 2的bits次方
例如,
42 = 101010(二进制)
对 42 进行位左移操作:
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 进行位右移操作:
42 >> 1 = 21(二进制 010101)
42 >> 2 = 10(二进制 001010)
42 >> 4 = 2(二进制 000010)
示例 6:位右移
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 = 21
42>>2 = 10
42>>4 = 2