【发布时间】:2012-02-22 20:25:13
【问题描述】:
如何在 C 中仅使用位运算符获得 INT_MAX 的值?我预计~0 是1111111111(1 的补码,所以十进制-1)和~0 >> 1 是0111111111,这将是最大的,但它仍然是-1。
为什么会这样?如何通过位运算获得INT_MAX的值?
【问题讨论】:
标签: c bitwise-operators
如何在 C 中仅使用位运算符获得 INT_MAX 的值?我预计~0 是1111111111(1 的补码,所以十进制-1)和~0 >> 1 是0111111111,这将是最大的,但它仍然是-1。
为什么会这样?如何通过位运算获得INT_MAX的值?
【问题讨论】:
标签: c bitwise-operators
试试~0UL >> 1。问题是如果 C 处理有符号类型,它会进行符号扩展右移。这就是为什么你仍然得到负数的原因——因为它正在移动另一个 1 位以匹配那里的 1 位。 (这样-8 >> 1 会给出-4,因为您希望快速除以二。)
【讨论】:
~0UL >> 1 是 LONG_MAX。你需要~0U >> 1。也许也可以将其转换为int,所以它会有正确的类型。
for(x=0;x+1>x;x++); 相当强大,虽然速度很慢。
如果将负数右移,则该数字的新位可能为 1(以保持负数)。这就是你得到 -1 的原因。
编辑:您可以执行以下操作:
int i=1;
while (i<<1) i<<=1;
i=~i;
【讨论】:
E1 > 0 一个有符号类型的值,如果 E1 * 2^E2 在该类型中不可表示,则 E1 << E2 是未定义的行为,因此您的替代方案依赖于对这种未定义行为的特定解释。
如果您将0 视为无符号整数,编译器将不会执行有符号移位:
int i = ~0U >> 1;
这会给你INT_MAX
【讨论】:
据我所知,除了使用INT_MAX 宏之外,没有可移植的解决方案。请参阅我的长期问题:
Programmatically determining max value of a signed integer type
以及它所基于的问题:
C question: off_t (and other signed integer types) minimum and maximum values
【讨论】:
(1
也是。这是一个旧线程,但无论如何我都会为任何搜索它的人发布它。但这并不完全是按位计算的,它假设您机器上的“int”是 32 位的。
【讨论】:
#include <stdio.h>
int main(){
int max = ~0U >> 1;
int min = ~max;
printf("Max = 0x%X, min = 0x%X", max, min);
return 0;
}
输出:
Max = 0x7FFFFFFF, min = 0x80000000
【讨论】:
以下是查找任何有符号整数类型的 MIN/MAX 的方法。但是,我假设左移会进行算术移位并用零填充空白,这对于大多数编译器都是正确的。
#define MIN_OF_SIGNED_TYPE(type) ((type)1 << (sizeof(type) * 8 - 1))
#define MAX_OF_SIGNED_TYPE(type) (~MIN_OF_SIGNED_TYPE(type))
#define MY_INT_MIN MIN_OF_SIGNED_TYPE(int)
#define MY_INT_MAX MAX_OF_SIGNED_TYPE(int)
【讨论】:
int int_max = (unsigned int)-1 >> 1;
【讨论】: