通常需要将数据类型表示为位序列,并在整个长度的循环内获取它们。虽然我发现((b >> i) & 1)
更直观,但最近我看到一本书使用了(b&(1<<i))
。他们中的任何一个是更有利还是更有效,如果其中一个是,为什么?
答案 0 :(得分:3)
假设您使用它来测试一点(因此结果的差异是无关紧要的),它取决于上下文以及编译器对它做什么以及其他因素。
例如,当使用GCC 7.3为现代x86编译时,它们是exactly the same,两者都可以编译为这个序列:
sarx eax, edi, esi
and eax, 1
当使用结果实际做出决定(而不是实现布尔值)时,代码仍然是相同的。显然,如果代码是相同的,效率就没有差别。 Clang喜欢使用bt
和setc
(或在适当时使用cmov或控制流中的标志),但对两个片段也做同样的事情。 MSVC确实以不同的方式编译片段,并且在某种意义上可能“更喜欢”1 << i
公式。
实现b & (1 << i)
字面上(我没有观察到任何编译器实际上做过)需要额外的指令将常量1加载到寄存器中,尽管这并不一定意味着需要额外的时间(尽管可以):创建1独立于其他所有内容,因此它可以在其他所有内容之前执行,然后移位独立于b
,因此它可以在i
准备就绪后执行但在b
之前。
答案 1 :(得分:2)
哪个更有利?
取决于您需要的数据。
((b >> i) & 1) gives you a 1 or 0.
(b & (1 << i)) gives you a 0 or 2^i.
哪个更有效?
效率差异在他们之间可以忽略不计。另外,不同的架构和代码编译的区别也不同。