如何测试有符号或无符号整数的最高有效位?
How to test the most significant bit of signed or unsigned integer?
给定一个保证为某种整数的 clock_t
数据类型,您如何使用可移植的 C 代码测试最高有效位的值?换句话说,我需要这个函数的定义:
bool is_msb_set(clock_t clock);
但问题在于:您不知道 clock_t
的大小,也不知道它是有符号还是无符号(但假设 "signed" 是双补)。
我的第一个想法是这样做:
const clock_t MSB = 1 << ((sizeof(clock_t) * 8) - 1);
bool is_msb_set(clock_t value) {
return value & MSB;
}
但如果 clock_t
是有符号值,则 MSB 的定义会溢出。也许我想多了,但我很难过。
不加掩码直接测试值即可:
bool is_msb_set(clock_t value) {
if (value < 0) return 1;
return value >> (sizeof(clock_t) * CHAR_BIT - 1);
}
如果 >>
运算符的左侧有 "a signed type and a negative value, the resulting value is implementation-defined",请参阅 C11 6.5.7p5。
因为我们assumed "signed" is twos-compliment
,我可以只测试value
是否小于0,最高有效位将始终设置为1。如果它不是负数,则为正数,并且 clock_t
已签名,则 >>
已正确定义。
如果 clock_t
是无符号的,那么 value < 0
将始终 return 0
并且很可能应该被编译器优化掉。
如果 clock_t
不是整数类型(例如 float
或 double
),则代码不应编译,因为 >>
的操作数需要有整数类型。所以它只适用于整数类型。
你可以做的是将它转换为一个保证足够大(那么长?)的整数,然后 然后 对 1 << ((sizeof(clock_t) * 8) - 1);
进行测试。
我也会首先断言sizeof(clock_t) <= sizeof(long)
。
我想我们可以先检查clock_t
是有符号的还是无符号的,然后据此进行。
bool is_msb_set(clock_t value) {
if ((clock_t)-1 < 0) {
/* clock_t is signed */
return value < 0;
} else {
/* clock_t is unsigned */
return ((value << 1) >> 1) ^ value;
}
}
给定一个保证为某种整数的 clock_t
数据类型,您如何使用可移植的 C 代码测试最高有效位的值?换句话说,我需要这个函数的定义:
bool is_msb_set(clock_t clock);
但问题在于:您不知道 clock_t
的大小,也不知道它是有符号还是无符号(但假设 "signed" 是双补)。
我的第一个想法是这样做:
const clock_t MSB = 1 << ((sizeof(clock_t) * 8) - 1);
bool is_msb_set(clock_t value) {
return value & MSB;
}
但如果 clock_t
是有符号值,则 MSB 的定义会溢出。也许我想多了,但我很难过。
不加掩码直接测试值即可:
bool is_msb_set(clock_t value) {
if (value < 0) return 1;
return value >> (sizeof(clock_t) * CHAR_BIT - 1);
}
如果 >>
运算符的左侧有 "a signed type and a negative value, the resulting value is implementation-defined",请参阅 C11 6.5.7p5。
因为我们assumed "signed" is twos-compliment
,我可以只测试value
是否小于0,最高有效位将始终设置为1。如果它不是负数,则为正数,并且 clock_t
已签名,则 >>
已正确定义。
如果 clock_t
是无符号的,那么 value < 0
将始终 return 0
并且很可能应该被编译器优化掉。
如果 clock_t
不是整数类型(例如 float
或 double
),则代码不应编译,因为 >>
的操作数需要有整数类型。所以它只适用于整数类型。
你可以做的是将它转换为一个保证足够大(那么长?)的整数,然后 然后 对 1 << ((sizeof(clock_t) * 8) - 1);
进行测试。
我也会首先断言sizeof(clock_t) <= sizeof(long)
。
我想我们可以先检查clock_t
是有符号的还是无符号的,然后据此进行。
bool is_msb_set(clock_t value) {
if ((clock_t)-1 < 0) {
/* clock_t is signed */
return value < 0;
} else {
/* clock_t is unsigned */
return ((value << 1) >> 1) ^ value;
}
}