【问题标题】:How to set last three bit of a byte efficiently?如何有效地设置一个字节的最后三位?
【发布时间】:2016-04-05 09:21:09
【问题描述】:

我想将字节的最后三位设置为特定值。归档此目标的最佳方式是什么?

我至少能想到两种解决方案……假设我有以下字节:1101 0110,并且想将最后三位设置为 011。

解决方案 1:

 1101 0110
&1111 1000 //and with mask to clear last three bits
|0000 0011 //add the target bits

解决方案2:

 1101 0110 >> 3 //shift right to remove last three
 0001 1010 << 3 //shift left to clear last three
|0000 0011 //add target bits

有没有更好/更短/更有效的方法?

【问题讨论】:

  • 毫无疑问,性能影响将是无限小的。但这个问题更多的是关于我对以最有效的方式编码事物的热情。所以速度的提高可能真的很小,但这是否是用较慢的方式编写它的原因,当它快速编写时只是代码中或多或少几个字符的问题......?
  • 这些优化的问题在于它们高度依赖于架构。 x68 上的 fastet 在三核上并不是最快的。您的架构手册应该能够为您提供轮班所需的周期数与 & 所需的周期数的信息。
  • 看,用显而易见的方式,易于理解的方式。易于调试的方式。 99.9% 的家庭开发人员会立即使用位掩码并继续进行重要的设计决策。

标签: c bit-manipulation bitwise-operators bit bit-shift


【解决方案1】:

最好的方式是说

b = (b & ~7u) | 3

因为3=0...0117u=0..111 是二进制的,而7u 的补码是~7u=11...1000,所以操作就是你想要的。它首先清除最后三位(通过b &amp; ~7u),然后设置第一位和第二位(通过与3 进行按位或)。

【讨论】:

  • 而且,这两个解决方案确实是“低指令”。有最快的方法可以做到这一点,移位和逻辑操作对于proc来说真的很快。任何其他方式都会非常慢。
  • 最后 三个 位:掩码应该是 ~7u 或 7u
  • 您的解决方案(位掩码 + OR)看起来像我的第一个解决方案。那么使用 AND 的位掩码是否比两次移位更快?还有一个问题——为什么面具是 7u 而不是 7?因为它必须是无符号的才能构建补码?
  • 我不知道,但它更直观;我想这取决于 CPU 需要多少个周期来进行移位与 AND。关于u,是的。
【解决方案2】:

如果 C 源代码中有 &gt;&gt;,那 是否意味着生成的代码会有移位指令。

((x&gt;&gt;3)&lt;&lt;3) | 3 可能生成与(x &amp; ~7) | 3 完全相同的代码。编译器在优化方面非常复杂。

使用最简单的@Martin James

推荐@blazs解决方案,因为它易于理解并且很好地处理有符号整数问题。

(x & ~7u) | 3

【讨论】:

    【解决方案3】:

    我建议您执行第二个解决方案,确保它取决于您的硬件架构,但几乎总是 SHIFT 操作比 ADD 快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-13
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 2019-01-02
      • 2010-10-19
      相关资源
      最近更新 更多