我在 this MSDN 页面上找到了以下代码。
(((Width * Planes * BitCount + 31) & ~31) / 8) * abs(Height)
这确实可以在 C# Visual Studio 2010 中编译。数字 31 前面的波形符“~”到底在做什么?我以前从未在表达式中见过这种语法。
这就是按位求补运算符,也称为按位求反。
它是按位补运算符。
基本上,它会翻转位:
0xffff0000 == ~0x0000ffff
在您发布的代码中,执行
& ~31
确保最后 5 位为 0(按位和 11111 的补码,即 00000)。
您翻到手边的 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
是具有基础类型 E
的枚举类型 U
的表达式)与计算 unchecked((E)(~(U)x))
完全相同。仅当操作数类型为枚举类型时,一元运算符重载决策才会考虑此运算符 E
(第 14.2.3 节)。
上面定义的未提升预定义按位补运算符的提升(§14.2.7)形式也是预定义的。
在您的情况下,
~31
与~ 0x0000001F
相同。 0x0000001F
的按位补码是 0xFFFFFFE0
。我无法理解为什么他们不直接写出他们想要的实际面具。
这是按位求补运算符 - 它只是将所有 0 位变为 1,反之亦然...请参阅 MSDN 参考文献。
在您的具体情况下,它只会创建(
31 = 0x1F
):
~0x1F = 0xFFFFFFE0
它与
bitwise and (&)
一起使用,因此基本上消除了最后 5 位。
~31 = 31 的按位求反,在这种特殊情况下用于将
(Width * Planes * BitCount + 31)
的前 5 位(从 LSB 开始)保持为零