在表达式中,波浪号代表什么意思?

52

可能是重复问题:
C#枚举中的波浪号(~)是什么?

我在这个MSDN页面上找到了以下代码片段。

(((Width * Planes * BitCount + 31) & ~31) / 8) * abs(Height)

在C# Visual Studio 2010中确实可以编译此代码。请问数字31前面的波浪线"~"具体是做什么用的?我以前从未在表达式中见过这种语法。


2
这是按位补码。请参见下面的链接。按位补码运算符如何工作 - Nerdtron
以下是C#运算符列表,仅供日后参考。 C#运算符 - Conrad Frix
6个回答

71

~ - 按位取反运算符, 基本上是反转二进制位。

31 的二进制格式是 11111,所以 ~31 == 11111111111111111111111111100000,或者是 0xFFFFFFE0 十六进制。


+1 是最容易理解和最清晰的答案。 - James Hatton
14
这个例子不正确,因为前导零也被倒置了。也就是说,~31 = ~0x0000001F = 0xFFFFFFE0 - JimiLoe
4
这个例子是不正确的。 31的二进制补码表示为00000000000000000000000000011111(如果是32位计算,则为0000001F十六进制),"~" 运算符会翻转位,因此答案将是11111111111111111111111111100000,如果将其转换为十进制,答案为-32。如果是64位,则31的二进制补码为0000000000000000000000000000000000000000000000000000000000011111,并且“~”翻转位,这仍然相当于-32。据我所知,没有运行C#的6位PC,所以它是错误的。 如果有6位PC,则这是正确的。 - Isham Mohamed

40

11

这是按位补码运算符

它基本上是翻转比特位:

0xffff0000 == ~0x0000ffff
在您发布的代码中,执行& ~31可以确保最后5位为0(对11111取反的按位与结果是00000)。

8
你翻开你方便携带的ISO/IEC 23270:2006 - 信息技术 - 编程语言 - C#,并翻到神圣经典的§14.6.4。在那里,你会找到:

14.6.4 按位取反运算符

对于形如~x的操作,将应用一元运算符重载(§14.2.3)以选择特定的运算符实现。操作数将转换为所选运算符的参数类型,并且结果的类型是运算符的返回类型。预定义的按位取反运算符有:

int   operator ~( int   x ) ;
uint  operator ~( uint  x ) ;
long  operator ~( long  x ) ;
ulong operator ~( ulong x ) ;

对于这些运算符,操作的结果是x的按位补码。

每个枚举类型E都隐式提供了以下按位补码运算符:

E operator ~(E x);

评估表达式x,其中x是具有基础类型U的枚举类型E的表达式时,~x的结果与评估unchecked((E)(~(U)x))完全相同。只有当操作数类型是枚举类型E(§14.2.3)时,该运算符才会被一元运算符重载解析器考虑。
上述未提升的预定义按位补码运算符的升级形式(§14.2.7)也是预定义的。
在您的情况下,~31 等同于 ~ 0x0000001F0x0000001F 的按位补数是 0xFFFFFFE0。为什么他们不直接写出他们想要的实际掩码,这超出了我的理解范围。

1

这是按位取反运算符 - 它将所有的0位变成1,反之亦然... 详见MSDN参考

在你的特定情况下它只会创建 (31 = 0x1F):

~0x1F = 0xFFFFFFE0

它与 按位与 (&) 一起使用,因此基本上它会取消掉最后5位。


0

~31 = 对31进行按位取反,这里特别用于将(Width * Planes * BitCount + 31)的前5位(从LSB开始)保持为零。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接