c++ - 在没有条件/分支的情况下使用逻辑 AND/OR

标签 c++ bit-manipulation bitwise-operators boolean-logic short-circuiting

我正在尝试编写一个函数来计算一些位标志,同时避免使用分支或条件:

uint8_t count_descriptors(uint8_t n)
{
    return 
    ((n & 2)   && !(n & 1))   +
    ((n & 4)   && !(n & 1))   +
    ((n & 8)   && !(n & 1))   +
    ((n & 16)  && !(n & 1))   +
    ((n & 32)  && 1       )   +
    ((n & 64)  || (n & 128))  ;
}

bit 0 不直接计数,bit 1-4 仅在 bit 0 未设置时才考虑,bit 5 无条件考虑,bit 6-7 只能计数一次。

但是,我知道 bool 值 && 和 ||使用短路评估。这意味着它们的使用创建了一个条件分支,正如您在此类示例中看到的那样:if( ptr != nullptr && ptr->predicate()) 保证第二个子表达式中的代码不是如果结果是从第一个子表达式计算的短路,则执行。

问题的第一部分:我需要做什么吗?由于这些是没有副作用的纯算术运算,编译器会创建条件分支吗?

第二部分:我明白按位 bool 运算符不会短路求值,但唯一的问题是位不对齐。屏蔽第 n 位的结果是 2^n 或零。

使 (n & 16) 等表达式的计算结果为 1 或 0 的最佳方法是什么?

最佳答案

我假设“bit 6-7 can only counted once”你的意思是只有其中一个被计算在内

在这种情况下,这样的事情应该可行

uint8_t count_descriptors(uint8_t n)
{
    uint8_t retVar;

    retVar = (n&1)*(n&2 >> 1) + 
             (n&1)*(n&4 >> 2) + 
             (n&1)*(n&8 >> 3) +
             (n&1)*(n&16 >> 4) + 
             (n&32 >> 5) + 
             (int)((n&64 >> 6) + (n&128 >> 7) >= 1)

    return retVar;

}

关于c++ - 在没有条件/分支的情况下使用逻辑 AND/OR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47403614/

相关文章:

c++ - 如何编译静态链接除一个库之外的所有库 (G++)

assembly - 了解 bset 和 bclr

JavaScript trunc() 函数

c++ - 打包结构和不打包没有代码重复

delphi - 将Delphi按位运算转换为Cobol

c - 向后打印无符号字符的二进制表示形式?

c++ - 我在这里使用全局状态吗,有没有更好的方法来做到这一点?

c++ - 一个函数检测参数类型,值,以及另一个函数的名称和返回值?

c++ - 如何让 Q_PROPERTY 在设计 View 中显示

c++ - 在 32 位字位模式中找到 "edges"