我有一个关于在C中构造位掩码的问题。我需要掩盖'long int'中最不重要的一半,所以我只剩下上半部分。无论我是在64位还是32位平台上,我都需要确保它能够掩盖 half 。我看到__WORD_SIZE在limits.h中定义。最初我这样做:
#define UPPER(X) ( X & ( ~0 << (__WORDSIZE/2) ) )
最正确有效的方法是什么?
答案 0 :(得分:13)
我建议你使用像
这样的东西#define UPPER(x) (x & (~0 << (sizeof(x) * 4)))
即使limits.h不存在或者由于某种原因__WORDSIZE未定义,这也可以工作。此外,它也适用于其他类型,所以你可以例如在int,short,char等上使用它。
任何体面的编译器都会计算
sizeof(x) * 4
在编译时(因为它们都是常量),这意味着你不必担心那里有任何性能损失。
编辑:纠正错误 - sizeof以字节为单位返回大小而不是位,因此我们必须乘以4(8/2)才能得到正确的结果。感谢那些指出这一点的人。
编辑2:如果你想变得非常迂腐,你可以使用
#define UPPER(x) (x & (~0 << (sizeof(x) * CHAR_BITS / 2)))
CHAR_BIT是在 limits.h 中定义的常量 - 它指定字符中的位数,并且是特定于平台的。但是,这并不是必需的(一般情况下),因为AFAIK通常没有使用ATM的平台使用非标准大小的字节。
答案 1 :(得分:3)
#define UPPER(X) ( (X) & ( ~0L << ( ( sizeof(long) * CHAR_BIT ) / 2 ) ) )
答案 2 :(得分:1)
你拥有的是好的。常量传播会将( ~0 << (__WORDSIZE/2) )
折叠为单个值,只要__WORDSIZE
是常量,就是这样。
答案 3 :(得分:1)
我尽量不聪明。我会做这样的事情:
static inline int UPPER(long int x) {
if (sizeof(long int) == 8)
return x & 0xffffffff00000000;
else if (sizeof(long int) == 4)
return x & 0xffff0000;
}
让编译器和优化器完成工作,代码对于任何未来的维护者都是清楚的。如果将来支持36位处理器是一个问题,添加一个触发一些错误条件的else子句,这样你就可以在它出现时处理它。