何时在 C# 中使用 Shift 运算符 << >>?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1933597/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When to use Shift operators << >> in C#?
提问by Junior Mayhé
I was studying shift operators in C#, trying to find out when to use them in my code.
我正在研究 C# 中的移位运算符,试图找出何时在我的代码中使用它们。
I found an answer but for Java, you could:
我找到了一个答案,但对于 Java,您可以:
a) Make fasterinteger multiplication and division operations:
a) 进行更快的整数乘法和除法运算:
*4839534 * 4* can be done like this: 4839534 << 2
*4839534 * 4* 可以这样做: 4839534 << 2
or
或者
543894 / 2can be done like this: 543894 >> 1
543894 / 2可以这样做:543894 >> 1
Shift operations much more faster than multiplication for most of processors.
对于大多数处理器,移位操作比乘法快得多。
b) Reassembling byte streams to int values
b) 将字节流重组为 int 值
c) For accelerating operations with graphics since Red, Green and Blue colors coded by separate bytes.
c) 用于加速图形操作,因为红色、绿色和蓝色由单独的字节编码。
d) Packing small numbers into one single long...
d) 将小数字打包成一个长...
For b, c and d I can't imagine here a real sample.
对于 b、c 和 d,我无法想象这是一个真实的样本。
Does anyone know if we can accomplish all these items in C#? Is there more practical use for shift operatorsin C#?
有谁知道我们是否可以在 C# 中完成所有这些项目?C# 中的移位运算符有更实际的用途吗?
采纳答案by GraemeF
There is no need to use them for optimisation purposes because the compiler will take care of this for you.
没有必要将它们用于优化目的,因为编译器会为您处理这些。
Only use them when shifting bits is the real intent of your code (as in the remaining examples in your question). The rest of the time just use multiply and divide so readers of your code can understand it at a glance.
仅当移动位是您的代码的真正意图时才使用它们(如您问题中的其余示例)。其余时间只使用乘法和除法,这样您的代码的读者就可以一目了然。
回答by cdonner
Check out these Wikipedia articles about the binary number systemand the arithmetic shift. I think they will answer your questions.
查看这些关于二进制数系统和算术移位的维基百科文章。我想他们会回答你的问题。
The shift operators are rarely encountered in business applications today. They will appear frequently in low-level code that interacts with hardware or manipulates packed data. They were more common back in the days of 64k memory segments.
在当今的业务应用程序中很少遇到班次运算符。它们将频繁出现在与硬件交互或操作打包数据的低级代码中。在 64k 内存段的时代,它们更常见。
回答by Mark Wilkins
Unless there is a very compelling reason, my opinion is that using clever tricks like that typically just make for more confusing code with little added value. The compiler writers are a smart bunch of developers and know a lot more of those tricks than the average programmer does. For example, dividing an integer by a power of 2 is faster with the shift operator than a division, but it probably isn't necessary since the compiler will do that for you. You can see this by looking at the assembly that both the Microsoft C/C++ compiler and gcc perform these optimizations.
除非有一个非常令人信服的理由,否则我的观点是,使用这样的聪明技巧通常只会使代码更加混乱而几乎没有附加值。编译器编写者是一群聪明的开发人员,并且比普通程序员了解更多这些技巧。例如,使用移位运算符将整数除以 2 的幂比使用除法更快,但这可能不是必需的,因为编译器会为您执行此操作。您可以通过查看 Microsoft C/C++ 编译器和 gcc 执行这些优化的程序集来了解这一点。
回答by aaaantoine
I will share an interesting use I've stumbled across in the past. This example is shamelessly copied from a supplemental answer to the question, "What does the [Flags] Enum Attribute mean in C#?"
我将分享我过去偶然发现的一个有趣的用法。这个例子是从问题的补充答案中无耻地复制过来的,“ [Flags] Enum Attribute 在 C# 中是什么意思?”
[Flags]
public enum MyEnum
{
None = 0,
First = 1 << 0,
Second = 1 << 1,
Third = 1 << 2,
Fourth = 1 << 3
}
This can be easier to expand upon than writing literal 1, 2, 4, 8, ...
values, especially once you get past 17 flags.
这比编写文字1, 2, 4, 8, ...
值更容易扩展,尤其是当你超过 17 个标志时。
The tradeoff is, if you need more than 31 flags (1 << 30
), you also need to be careful to specify your enum as something with a higher upper bound than a signed integer (by declaring it as public enum MyEnum : ulong
, for example, which will give you up to 64 flags). This is because...
权衡是,如果您需要超过 31 个标志 ( 1 << 30
),您还需要小心地将您的枚举指定为具有比有符号整数更高的上限(public enum MyEnum : ulong
例如,通过将其声明为 ,这将使您最多64 个标志)。这是因为...
1 << 29 == 536870912
1 << 30 == 1073741824
1 << 31 == -2147483648
1 << 32 == 1
1 << 33 == 2
By contrast, if you set an enum value directly to 2147483648, the compiler will throw an error.
相比之下,如果直接将枚举值设置为 2147483648,编译器会抛出错误。
As pointed out by ClickRick, even if your enum derives from ulong, your bit shift operation has to be performed against a ulong or your enum values will still be broken.
正如 ClickRick 所指出的,即使您的枚举来自 ulong,您的位移操作也必须针对 ulong 执行,否则您的枚举值仍然会被破坏。
[Flags]
public enum MyEnum : ulong
{
None = 0,
First = 1 << 0,
Second = 1 << 1,
Third = 1 << 2,
Fourth = 1 << 3,
// Compiler error:
// Constant value '-2147483648' cannot be converted to a 'ulong'
// (Note this wouldn't be thrown if MyEnum derived from long)
ThirtySecond = 1 << 31,
// so what you would have to do instead is...
ThirtySecond = 1UL << 31,
ThirtyThird = 1UL << 32,
ThirtyFourth = 1UL << 33
}