【发布时间】:2014-06-30 17:42:02
【问题描述】:
如果设置了input 的第 1、3、5、7、9、11、13 或 15 位之一,我希望 var 不等于 FALSE。
一个似乎相当普遍的解决方案是:
int var = 1 & (input >> 1) ||
1 & (input >> 3) ||
1 & (input >> 5) ||
1 & (input >> 7) ||
1 & (input >> 9) ||
1 & (input >> 11) ||
1 & (input >> 13) ||
1 & (input >> 15);
但是,我担心这会导致编译器生成不必要的长代码。
以下代码也将产生所需的结果。会不会更有效率?
int var = input & 0b1010101010101010;
谢谢!
【问题讨论】:
-
请注意,二进制文字 (
0b...) 是对 C 的一种非标准扩展。它们将出现在 C++14 中;因此,它们可能会到达 C1x,但不在 C11(当前标准)中。这并不是说它们不能被使用。这只是一个警告,并非每个编译器都会支持它,尽管所有编译器都会支持 0xAAAA。 -
请注意,您的替代方案不会产生与原来相同的结果;你需要写:
int var = (input & 0xAAAA) != 0;以获得相同的 0 或 1 输出。 -
为什么要写第一个怪物?如果使用位掩码进行与运算就足够了,那么就这样做。
-
@JonathanLeffler 用于信息二进制文字已在 C89 中提出并被拒绝(在 C89 和 C99 基本原理文档中:“由于缺乏先例和实用性不足,添加二进制常量的提议被拒绝")
-
@ouah:我同意这些评估,截至 1989 年和 1999 年。如果(并且它仍然是 if)C++14 经过并添加二进制文字,然后 C1x 支持的格局发生了巨大变化。他们会有“先例”和经验。它们可能会被添加到大多数 C 编译器中以与 C++ 兼容。 C++14 的另一个有趣的补充是数字中的引号分隔符:
0xFFFF'FFFF'FFAB'7891等。我很困惑选择'而不是_。引号的使用使临时解析器更加难以管理(而下划线会简单得多)。
标签: c optimization compiler-construction bit-shift