在大多数旧微处理器上,位运算比加减法运算稍快,通常比乘除法运算快得多。但在现代架构中,情况并非如此:位运算通常与加法速度相同(尽管仍然比乘法快)。
学习位运算技巧是否有实际意义,还是只是为了理论和好奇心呢?
位运算值得学习,因为它们有许多应用。它们的主要用途不是代替算术运算。密码学、计算机图形学、哈希函数、压缩算法和网络协议只是一些位运算非常有用的示例。
你从维基百科文章中引用的那句话只是试图提供有关位运算速度的一些线索。不幸的是,该文章未能提供一些很好的应用示例。
位运算仍然很有用。例如,可以使用它们使用单个变量创建“标志”,并节省指示各种条件所需的变量数量。关于算术操作的性能,最好让编译器进行优化(除非您是某种类型的专家)。
它们有助于理解二进制的“工作原理”,否则没有用处。实际上,我会说,即使按位操作在特定架构上更快,也应该由编译器利用这一点而不是你自己来完成。写出你的意思。
唯一有意义使用它们的情况是,如果您实际上将数字用作位向量。例如,如果您正在模拟某种硬件,并且变量表示寄存器。
如果您想执行算术运算,请使用算术运算符。
当然(对我来说)答案是肯定的:学习它们可能有实际原因。现在,例如,在典型处理器上,add
指令的速度与or
/xor
或and
相同,这意味着:add
在那些处理器上的速度与or
相同。
像加法、除法等指令速度的提高只是意味着现在在那些处理器上可以使用它们,并且不必太担心性能影响;但是过去和现在一样,通常不会将每个add
更改为位运算符以实现add
。也就是说,在某些情况下,这可能取决于哪些技巧:现在可能有些技巧必须被认为是教育性的而不是实用的;其他技巧仍然可能具有实际应用。
取决于你的问题是什么。如果你正在控制硬件,你需要一些方法来在整数中设置单个位。
购买一个 OGD1 PCI 板(开放图形卡),并使用 libpci 与之通信。http://en.wikipedia.org/wiki/Open_Graphics_Project
在大多数情况下,当您将整数乘以恰好是2的幂次方的常数时,编译器会优化为使用位移操作。但是,当移位也是一个变量时,编译器无法推断它,除非您明确使用移位操作。
一旦你开始考虑按位运算,你会发现有很多地方可以使用它。例如,我有两个文本缓冲区。我将一个写到另一个中,边写边用 REPLACEstring 替换所有 FINDstring 的出现。然后对于下一个查找替换对,我只需切换缓冲索引,这样我总是从 buffer [in] 写入到 buffer [out]。'in' 初始为 0,'out' 初始为1。在完成复制后,我只需编写 'in ^= 1; out ^= 1;'。在处理所有替换后,我只需将 buffer [out] 写入磁盘,此时不需要知道 'out' 是什么。
如果您认为这是低级别的,请考虑某些类似于 déjà vu 和其孪生兄弟 jamais vu 的心理错误是由大脑位错误引起的!
在处理IPv4地址时,经常需要进行位运算,以确定对等方的地址是否在可路由网络内或必须转发到网关,或者对等方是否属于防火墙规则允许或拒绝的网络。位运算是发现网络广播地址所必需的。
处理IPv6地址需要相同的基本位级操作,但由于它们非常长,我不确定它们是如何实现的。我敢打赌,它们仍然使用适合架构的数据“片段”上的位运算符来实现。