你是否曾经在真实项目中使用过位移操作?

83

你是否曾经在实际编程项目中使用过 位移操作?大多数(如果不是全部)高级语言都有这种操作符,但是什么情况下才需要使用它们呢?

42个回答

60

我仍然为没有硬件浮点支持的系统编写代码。在这些系统中,几乎所有的算术运算都需要使用位移。

此外,您需要使用位移来生成哈希值。多项式算术(CRC、Reed-Solomon Codes是主流应用)也使用位移。

然而,仅仅因为它们方便且能够精确地表达作者的意图才使用了位移。如果你想的话,你可以通过乘法来模拟所有的位移操作,但那会更难写,不易读,并且有时还会更慢。

编译器会检测到可以将乘法转换为位移的情况。


38

是的,我经常使用它们。在嵌入式硬件上,位掩码非常常见,因此位操作很重要。在游戏编程中,当您需要尽可能地提高性能时,位操作也很重要。

编辑: 此外,我经常使用它们来操纵位图,例如更改颜色深度或转换RGB<->BGR。


赞同。我做了很多嵌入式编程,位移操作是常见的操作。 - e.James
这里是RGB<->BGR转换。 - Neil N

26
  • 为枚举类型创建漂亮的标志值(而不是手动输入1、2、4...)
  • 从位域中解包数据(许多网络协议使用它们)
  • Z曲线遍历
  • 性能技巧

我想不出有多少情况会使用它们。通常情况下,问题是特定的,而采用位运算将产生最佳结果(通常是在时间和/或空间性能方面)。


您可能需要将两个“short”存储在ASP.net中的Session状态的一个“int”字段中,以避免读取和锁定Session以读取两个单独值所带来的开销。此外,还可以节省在Session中存储两个值所需的内存开销。 - David d C e Freitas

15

我经常使用它们的其中一个场合是在为跨平台应用程序转换整数的字节序时。它们有时还会与其他位操作符一起用于2D图形处理中。


赞同,编写一个EBCDIC字符集的转换器。不幸的是,这实际上是在高级语言中进行低级别的工作,但在某些情况下是必要的。 - Michael Meadows

9

我已经使用过它们几次,但基本上都是用于解析二进制文件格式。


7

位移操作是快速的。在除法和取模运算之前,它们就已经被实现在CPU指令集中了。许多人用位移操作来进行像在纸上计算器上简单的算术运算,但这些算术运算在我们的CPU上不可用。

例如:

  • 我曾经在项目中使用位移操作来将大复合数分解成它们的质因数。
  • 我还使用位移操作来找到任意大整数的平方根和立方根。

请问您能否提供一个示例,展示如何使用它来找到立方根或平方根?我有点不明白这个怎么做。 - Xsmael

5

是的,仍然需要。

例如,在我的工作中,我们开发软件通过串口COMx与PLC通信。必须处理字节内的位,我们每天都使用左/右移位和逻辑运算符OR、XOR、AND。

例如,假设我们需要打开一个字节中从右往左数第3个位:

00001001 -> 00001101

使用以下方法更加高效:

Byte B;

B := B OR 4; //100

改为:

Byte B = 0;
String s;  // 0 based index

s = ConvertToBinary (B);
s[5] = "1";
B := ConvertToDecimal (s);

致敬。


1
你可能希望添加为什么4与第三位比特相关(从右到左)。 - HCP
1
为什么是s[5]?不应该是S[2]吗? - IamIC
2
B := B XOR 4; 在这种情况下,要打开特定的位,难道不应该只使用OR吗?XOR不是用于切换的吗?https://dev59.com/z3VD5IYBdhLWcg3wOo5h - Hari
@Hari,你是对的。我已经纠正了它。 - Carlos Eduardo Olivieri
@IamIC,它是一个字节(8位)。 - Carlos Eduardo Olivieri

4
是的,我有过这样的经历。通常情况下,它主要出现在低级编程中,例如开发设备驱动程序。但是,我曾经参与了一个C#项目,需要开发一个接收医疗设备数据的Web服务。所有设备存储的二进制数据都被编码为SOAP数据包,但是这些二进制数据又被压缩和编码了。因此,为了解压缩,您需要进行大量的位操作。此外,您还需要进行大量的位移操作来解析出任何有用的信息,例如设备序列号是第二个字节的下半部分之类的内容。 此外,我也看到过一些在.NET(C#)世界中使用位掩码和标志属性的人,但我个人从未有过这方面的需求。

4
当我使用汇编语言编写代码时,我的代码充满了位移和掩码操作。
在C语言中也经常这样做。
在JavaScript或服务器语言中并没有太多这样的操作。
现代最好的用途可能是遍历以1和0表示的布尔值的紧凑数组。我过去总是在汇编中左移并检查符号位,但在高级语言中,您可以与一个值进行比较。
例如,如果您有8个位,可以使用“if (a>127) {...}”来检查顶部位。然后左移(或乘以2),与127进行“and”运算(或者如果设置了最后一位,则进行256的减法),再次执行相同操作。

3

没错。我之前必须编写加密算法,这绝对会用到它们。

当使用整数等来跟踪状态时,它们也非常有用。


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