我创建了一个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));
运行结果截图:
又进行了测试:
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));
运行结果:
这个问题的本质在于 -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。