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