按位取反运算符

3
你们能解释一下以下程序吗?
int main() 
{   
 int max = ~0; 
 printf("%d\n",max);    
 return 0; 
}

AFAIK ~会翻转位。在这种情况下,即~0将把所有位设置为1。因此,max变量应该包含MAX值,但我得到的输出是-1。所以,有没有人能告诉我为什么我得到的输出是-1。

4个回答

6
你为什么期望获得“最大值”?在二进制补码表示中,全1的比特模式代表-1。这就是它的方式。
在二进制补码表示中,最大值由01111...1比特模式表示(即第一位为0)。你得到的是1111...1,显然是负数,因为第一个比特位——符号位——是1。
如果你想要一个例子,其中补码零产生“最大值”,请使用无符号表示。
int main() {   
  unsigned max = ~0u; 
  printf("%u\n", max);    
}

请注意,变量/表达式的类型和格式说明符(%u)必须匹配才能正常工作。如果它们不匹配,则会出现未定义的行为。 - R.. GitHub STOP HELPING ICE

1

以上答案已经解释了 ~0 为什么等于 -1。

如果你想要得到整型的最大值,可以引入 limits.h 库并使用其中声明的常量。

INT_MAX 可以给你有符号整型的最大值。 UINT_MAX 可以给你无符号整型的最大值。

#include <stdio.h>
#include <limits.h>

int main()
{
printf( "Max signed int value: %d \n", INT_MAX);
printf("Max unsigned int value: %u \n", UINT_MAX );
return 0;
}

1

这是正确的输出,因为您正在使用有符号的int数据类型。 您需要了解二进制补码负数表示法。 所有位都是1不是最大的负值,就像您的程序输出的-1一样。 在32位情况下,最大的负有符号值是最高有效位设置为1,其余所有位为零,即0x80000000。 在32位情况下,最大的正有符号值是0x7fffffff。


0
这个问题很久以前就提出了,但为了后人的利益:
如果您将 ~0 打印为 int 和 hex,可能会更好地帮助您理解:
printf("compliment of zero %d\n", (~0));
printf("compliment of zero 0x%x\n", (~0));

输出:
零的补码为-1
零的补码为0xffffffff


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接