在GNU C中获取/设置整数最高位的最便携方法是什么?
这是彭博采访问题。那个时候我没有给出最好的答案。有人可以回答吗?
由于
答案 0 :(得分:5)
首先,请注意,如果我们谈论有符号整数,就没有可移植的方法来访问最高位;标准中没有定义单个可移植表示,因此“顶部位”的含义原则上可以变化。另外,C不允许直接访问按位表示;你可以作为char
缓冲区访问int,但你不知道'顶部位'的位置。
如果我们只关注有符号整数的非负范围,并假设所述范围的大小是2的幂(如果不是,那么我们需要再次关注有符号的表示):< / p>
#define INT_MAX_BIT (INT_MAX - (INT_MAX >> 1))
#define SET_MAX_BIT(x) (x | INT_MAX_BIT)
#define CLEAR_MAX_BIT(x) (x & ~INT_MAX_BIT)
类似的方法可以与无符号整数一起使用,它可以用来获得真正的顶部位。
答案 1 :(得分:5)
如果类型未签名,则很容易:
(type)-1-(type)-1/2
对于签名值,我不知道。如果你找到了一种方法,它将在SO上回答几个未解答的问题:
C question: off_t (and other signed integer types) minimum and maximum values
Is there any way to compute the width of an integer type at compile-time?
也许其他人。
答案 2 :(得分:2)
这是一个愚蠢的,使用:
Built-in Function: int __builtin_clz (unsigned int x)
Returns the number of leading 0-bits in x, starting at the most
significant bit position. If x is 0, the result is undefined.
首次尝试:
int get_msb(int x) { return x ? __buildin_clz(x) == 0 : 0; }
注意:C的一个怪癖是指定int
或unsigned int
参数的函数可以在没有警告的情况下使用其他类型调用。但是,这可能涉及转换--C ++标准4.7.2说:
如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模2n,其中n是用于表示无符号类型的位数)。 [注意:在二进制补码表示中,此转换是概念性的,并且位模式没有变化(如果没有截断)。 ]
这意味着如果位模式不是二进制补码表示可能会改变位模式,这将阻止此“解决方案”也可靠地工作。 : - (
下面的Chris的评论提供了一个解决方案(此处作为函数而不是预处理器宏合并):
int get_msb(int x) { return x ? __buildin_clz(*(unsigned*)&x) == 0 : 0; }
答案 3 :(得分:1)
这个有什么问题?
int get_msb(int n){
return ((unsigned)n) >> (sizeof(unsigned) * CHAR_BIT - 1);
// or, optionally
return n < 0;
};
int set_msb(int n, int msb){
if (msb)
return ((unsigned)n) | (1ULL << (sizeof(unsigned) * CHAR_BIT - 1));
else return ((unsigned)n) & ~(1ULL << (sizeof(unsigned) * CHAR_BIT - 1));
};
它负责字节顺序,字节中的位数,以及1的补码。
答案 4 :(得分:0)
#define HIGH_BIT(inttype) (((inttype)1) << (CHAR_BIT * sizeof(inttype) - 1))
示例用法:
ptrdiff_t i = 4711;
i |= HIGH_BIT(ptrdiff_t); /* set high bit */
i &= ~HIGH_BIT(ptrdiff_t); /* clear high bit */