【问题标题】:C Which Bit Hack Is Better And Why?C 哪个 Bit Hack 更好,为什么?
【发布时间】:2012-12-22 23:34:35
【问题描述】:
int n = 1; //Arbitrary value

for ( int i = 0;i < 8;i++ )
{
    printf( "%d",n & ( 1 << i ) ? 1 : 0 ); //Ternary
    printf( "%d",0 || n & ( 1 << i ) );    //Logical OR
}

在循环中的两个表达式中,哪一个更适合用于打印二进制值的 0 或 1 状态? (基本上打印二进制字符串表示)。

【问题讨论】:

  • 哈哈...它们都一样不可读。
  • 我不明白需要三元表达式或逻辑或。没有这些,也可以产生相同的输出。
  • 它们都很难阅读,所以从这个角度来看它们同样糟糕。并且可能也没有明显的效率差异,因为打印(可能)需要最多的时间,甚至是缓冲的。第二个可能更快,因为它没有潜在的跳跃。但是话又说回来,从三元运算符的跳转可能会被编译器优化掉。
  • 所以共识是:不可读。好吧好吧,我投降!

标签: c binary bit-manipulation


【解决方案1】:

最好的应该是

  (n >> i) & 0x1

与任何其他经过“布尔”转换的方法相比,它更可靠地无分支。

在可能和合理的情况下,最好向右移动,以便您感兴趣的位最终位于正确的位置以形成您需要的结果,从而消除任何额外步骤的需要。

【讨论】:

  • 非常好,我从来没有想过这样做。
  • 正确。很好的解决方案。谢谢!
  • 关于效率:根据我更古老的经验,testing n&(1>i)&1 when 'i 好一点' 是编译时常量,当 i 是变量时更糟。如果目标是获得 0 或 1 而不是条件测试,那可能不适用。但是,现在大多数编译器都会在内部将这种常见操作从一种形式转换为另一种形式,因此我不再在效率上做出这种选择。我最喜欢这个答案的可读性,因为它没有杂乱无章的概念“布尔”中间体,我认为这些中间体没有帮助。
【解决方案2】:

!!(n &amp; (1 &lt;&lt; i)) 怎么样? 还是(n &amp; (1 &lt;&lt; i)) != 0

我认为这两个都是比您提出的建议更好的选择(不,我没有自己想出 !! ,我在一些代码中阅读了它,并从那里拿起了它 - 它是例如,在 Xen 和 Linux 中经常使用)

为了使其更具可读性,可以考虑:

inline zero_or_one_bit(int n, int i)
{
    return !!(n & (1 << i));
}

【讨论】:

    【解决方案3】:

    不是左移,而是右移:

    for (int i = 7; i >= 0; --i)
        printf("%d", (n >> i) & 1);
    

    但是,从某种意义上说,如果1 &lt;&lt; i 是一条微编码指令(根据下面的 cmets 显然不太可能),它们可能都效率低下。

    这是一个只做恒定移位的版本:

    for (int i = 0, n2 = n; i < 8; i++, n2 <<= 1)
        printf("%d", (n2 >> 7) & 1);
    

    【讨论】:

    • Shift 指令在 AMD 处理器上没有微编码,我几乎可以肯定它们也没有在现代 Intel 处理器上,但这有点难以发现。我喜欢你的回答。
    【解决方案4】:

    我喜欢 AndreyT 的回答,但为了完整起见:您可以轻松地从该三元组中获得更多工作(您可能会惊讶于 %d 的成本有多高):

    putc( (n & ( 1 << i ))!=0 ? '1' : '0', stdout ); 
    

    是的,如果愿意的话

    putc(   ((n>>i) & 1) + '0',  stdout );
    

    【讨论】:

      猜你喜欢
      • 2011-01-22
      • 2016-12-17
      • 2011-01-09
      • 2018-10-07
      • 1970-01-01
      • 2010-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多