位运算符和位移运算符用于对整数(int、long 等)和布尔数据执行位级别操作。这些运算符在实际情况中不常用。
如果您有兴趣进一步探索,请访问 位运算符的实际应用。
C# 中可用的位运算符和位移运算符列于下表。
运算符 | 运算符名称 |
---|---|
~ | 位补码 |
& | 按位与 |
| | 按位或 |
^ | 按位异或 (XOR) |
<< | 按位左移 |
>> | 按位右移 |
按位或
按位或运算符由 |
表示。它对两个操作数的对应位执行按位或操作。如果其中任何一位是 1
,则结果为 1
。否则结果为 0
。
如果操作数是 bool
类型,则按位或操作等同于它们之间的逻辑或操作。
例如,
14 = 00001110 (In Binary) 11 = 00001011 (In Binary)
14 和 11 之间的按位 OR
操作
00001110 00001011 -------- 00001111 = 15 (In Decimal)
示例 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 (In Binary) 11 = 00001011 (In Binary)
14 和 11 之间的按位与操作
00001110 00001011 -------- 00001010 = 10 (In Decimal)
示例 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 (In Binary) 11 = 00001011 (In Binary)
14 和 11 之间的按位异或操作
00001110 00001011 -------- 00000101 = 5 (In Decimal)
如果您想了解更多关于按位异或的用法,请访问 XOR 运算符的魔力
示例3:按位XOR
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 (In Binary)
对 26 执行按位补码操作
~ 00011010 = 11100101 = 229 (In Decimal)
示例 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
(我们期望它是 229
)实际上是 -27
的 2 的补码表示。计算机中的负数以 2 的补码形式表示。
对于任何整数 n,n
的 2 的补码是 -(n+1)
。
十进制 | 二进制 | 2 的补码 |
---|---|---|
0 | 00000000 | -(11111111 + 1) = -00000000 = -0 (十进制) |
1 | 00000001 | -(11111110 + 1) = -11111111 = -256 (十进制) |
229 | 11100101 | -(00011010 + 1) = -00011011 = -27 |
在 2 的补码中,溢出值将被忽略。
26
的按位补码是 229(十进制),而 229
的 2 的补码是 -27
。因此,输出是 -27
而不是 229
。
按位左移
按位左移运算符由 <<
表示。<<
运算符将一个数字向左移位指定的位数。最低有效位会用零填充。
在十进制中,它等同于
num * 2bits
例如,
42 = 101010 (In Binary)
对 42 执行按位左移操作
42 << 1 = 84 (In binary 1010100) 42 << 2 = 168 (In binary 10101000) 42 << 4 = 672 (In binary 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 / 2bits)
例如,
42 = 101010 (In Binary)
对 42 执行按位左移操作
42 >> 1 = 21 (In binary 010101) 42 >> 2 = 10 (In binary 001010) 42 >> 4 = 2 (In binary 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