【发布时间】:2011-05-03 22:09:57
【问题描述】:
我已经编程了一段时间,但我从未使用过移位运算符。我可以看到它对计算 Tuple<T> 中的哈希码有什么帮助,但除此之外,
移位运算符在 C#/.NET 中何时以及如何使用?
【问题讨论】:
-
-1 因为在“相关”部分中有一个完全相同的副本。
-
@nantito - 好吧,他确实将 C# 放在了标签中。然而,另一个是精确的重复。
我已经编程了一段时间,但我从未使用过移位运算符。我可以看到它对计算 Tuple<T> 中的哈希码有什么帮助,但除此之外,
【问题讨论】:
一般来说,它不经常使用。但是在处理位级操作时它非常有用。例如打印出数值中的位
public static string GetBits(int value) {
var builder = new StringBuilder();
for (int i = 0; i < 32; i++) {
var test = 1 << (31 - i);
var isSet = 0 != (test & value);
builder.Append(isSet ? '1' : '0');
}
return builder.ToString();
}
【讨论】:
写出二的幂是很有用的。
快速:什么是 227?
答:1 << 27
写1 << 27 比134217728 更容易理解。
【讨论】:
Math.Pow(2, 27) 会比手动班次更好/自我记录 :)
enum 值中使用(你确实需要这样做)。它也(有点)慢。
我在处理硬件时经常使用它。这可能不是您在 C# 中经常做的事情,但该运算符是从 C/C++ 继承的,这是一个相当普遍的需求。
示例 1:
我刚从小端机器上得到一个长字,但我是大端机器。我该如何转换它?嗯,很明显是打电话给htonl()(你骗子)。其中一种手动方法是使用以下内容:
((source & 0x000000ff) << 24 ) |
((source & 0x0000ff00) << 8) |
((source & 0x00ff0000) >> 8) |
((source & 0xff000000) >> 24);
示例 2:
我有一个 DMA 设备,它只允许最大 512K 的长字访问。所以它需要我将传输大小的模 4 放入 DMA 传输控制寄存器的高 18 位(原因只有硬件人员才能理解)。为了争论起见,低位位将填充各种控制 DMA 操作的标志。可以这样完成:
dma_flags | ((length & 0xffffc) << 14);
这些可能不是你每天都在做的事情。但对于我们这些经常与硬件接口的人来说,它们是。
【讨论】:
如果您需要在不使用 * How to implement multiplication without using multiplication operator in .NET 的情况下进行乘法运算:)
或者写一个数独求解器Sudoku validity check algorithm - how does this code works?
在实践中,我唯一一次看到它在我的(有限的)体验中被用作(可以说)令人困惑的乘法方式(参见第一个链接)或与设置 BitFlags(上面的数独求解器)结合使用。
在 .NET 中,我很少需要在位级别上工作;但如果需要,能够转换很重要。
【讨论】:
位运算符有利于节省空间,但如今,空间已不再是问题。
在乘以 2 的幂时很有用
number<<power;
是number*2^power
当然还有除以 2 的幂:
number>>power;
另一个地方是枚举中的标志。
当你遇到类似的代码时
Regex re = new Regex(".",RegexOptions.Multiline|RegexOptions.Singleline);
使用RegexOptions.Multiline|RegexOptions.Singleline 的能力,即通过移位启用多个标志,这也允许它们是唯一的。
类似:
enum RegexOptions {
Multiline = (1 << 0),
Singleline = (1<<1)
};
【讨论】:
当需要操作单个位时,会使用位移位。例如,您会在许多加密算法中看到很多位移。
在优化中,它可以用来代替乘法/除法。左移等于乘以 2。右移等于除法。您可能不再看到这样做了,因为这种级别的优化通常是不必要的。
除此之外,我想不出很多使用它的理由。我以前见过它,但很少在真正需要它的情况下使用,通常可以使用更易读的方法。
【讨论】:
【讨论】: