c语言中关于int型变量以及INT_MIN的问题

我创建了一个int型变量my_int_min,并对他赋值为INT_MIN,可以得到:

my_int_min=-my_int_min=INT_MIN=-INT_MIN=-2147483648

所以,我预测表达式 !(-my_int_min&INT_MIN)的值应该为0,但实际运算结果为1,更加让我不理解的是表达式 !(-my_int_min&my_int_min) 的值为0。这是为什么呢?

代码如下:

 #include <limits.h>
 int my_int_min = INT_MIN;
 printf("INT_MIN=%d\t my_int_min=%d\t -INT_MIN=%d\t -my_int_min=%d\n", INT_MIN, my_int_min, -INT_MIN, -my_int_min);
 printf("!(-INT_MIN&INT_MIN)=%d\t !(-my_int_min&INT_MIN)=%d\n", !(-INT_MIN&INT_MIN), !(-my_int_min&INT_MIN));
 printf("!(-INT_MIN&my_int_min)=%d\t !(-my_int_min&my_int_min)=%d\n", !(-INT_MIN&my_int_min), !(-my_int_min&my_int_min));

运行结果截图:

img

又进行了测试:

printf("(-my_int_min&INT_MIN)=%d\t !(-my_int_min&INT_MIN)=%d\n", (-my_int_min&INT_MIN), !(-my_int_min&INT_MIN));

运行结果:

img


为什么逻辑非会出错呢?

这个问题的本质在于 -INT_MIN 和 INT_MIN 在二进制补码中的表示方式不同,其中 -INT_MIN 在二进制补码中的表示方式有可能与 INT_MIN 相同也有可能不同,取决于 INT_MIN 转换成二进制补码时的情况。
以 4 位二进制补码为例,假设 INT_MIN 等于 -8,即二进制补码为 1000,而 -INT_MIN 由正数取反加 1 得到,即 0111+1=1000,仍然等于 8。因此,在这种情况下,my_int_min=-my_int_min=INT_MIN=-INT_MIN=-8,!(-my_int_min&INT_MIN) 的结果为0。
而如果 INT_MIN 等于 -16,即二进制补码为 10000,而 -INT_MIN 的二进制补码为 10000,仍然等于 -16。因此,在这种情况下,my_int_min=-my_int_min=INT_MIN=-INT_MIN=-16,!(-my_int_min&INT_MIN) 的结果为1。

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^