C语言 如果没有位被设置,则设置所有位的无分支方式?

ruyhziif  于 2023-10-15  发布在  其他
关注(0)|答案(2)|浏览(94)

我正在寻找以下内容的无分支实现:

int f(int c) {
  if (c == 0) {
    return 0xffffffff; // all bits set
  } else {
    return c;
  }
}

我还没有找到任何聪明的方法来做到这一点。有什么花招吗?

mfuanj7w

mfuanj7w1#

正如Nick奥德尔所提到的,编译器很有可能已经将此代码编译为没有分支的指令。一个更有可能的公式是x - (x == 0)x - !!x,编译器通常可以通过使用CPU特定的特性来实现,而无需分支。你甚至可以尝试用一个纯粹基于位操作的公式来代替它。例如,((x - 1) & ~x) >> 31x无符号)只有当x == 0时才是1,否则是0。所以

x - (((x - 1) & ~x) >> 31)

将是f的完全无分支实现。在实践中,我希望它比编译器为其他公式生成的任何东西都要慢。

mcvgt66p

mcvgt66p2#

你可以将c转换为bool类型,如果设置了任何一位,则得到1,否则得到0。使用_Bool#include <stdbool.h>,除非使用C23。
然后减去1。如果前一步的结果为1,则将导致-1,即二进制补码系统中的所有1位。为了使其更易于移植,您可以首先将它们转换为unsigned类型。否则,结果将为0。
如果c为0,则上一步将得到一个数字,否则为0。如果数字为-1,则将数字与c进行位或运算,结果仅为-1,否则将c保持不变。

c | ((bool)c - 1)

相关问题