如果int n = INT_MIN,为什么(-n)/2是正数?



我一直在尝试使用最低符号32位整数。我写了下面的程序:

#include <iostream>
#include <climits>
int main() {
int n = 1<<31; //-2³¹
std::cout<<"a) n            = "<< (n)            <<"n";
std::cout<<"b) -n           = "<< (-n)           <<"n";
std::cout<<"c) -INT_MIN     = "<< (-INT_MIN)     <<"n"; //-Woverflow printed
std::cout<<"d) n/2          = "<< (n/2)          <<"n";
std::cout<<"e) n/-2         = "<< (n/-2)         <<"n";
std::cout<<"f) -n/2         = "<< (-n/2)         <<"n";
std::cout<<"g) (-n)/2       = "<< ((-n)/2)       <<"n";
std::cout<<"h) (-INT_MIN)/2 = "<< ((-INT_MIN)/2) <<"n"; //-Woverflow printed
}

我用g++编译它,得到以下输出:

a) n            = -2147483648
b) -n           = -2147483648
c) -INT_MIN     = -2147483648
d) n/2          = -1073741824
e) n/-2         = 1073741824
f) -n/2         = 1073741824
g) (-n)/2       = 1073741824
h) (-INT_MIN)/2 = -1073741824

第一个惊喜是例子b)和c),表明-n等于n,但我理解这一点:转换为int的-n = 2³² - n = 2³¹变成了-(2³¹)

然而,我无法理解示例f)。我发现一元减号运算符优先于除法(https://en.cppreference.com/w/cpp/language/operator_precedence)。我期望首先-n被计算为n,然后n/2应该是负的,如例d) -但事实并非如此。

我认为我误解了操作符优先级,所以我在示例g)中添加了括号,但这没有改变任何东西。

最后,在示例h)中,我将n更改为INT_MIN,具有相同的值,但操作结果变为负值!

我在理解例子f)和g)时遗漏了什么?在这种情况下,nINT_MIN有什么区别?我观察到的是特定于语言的,还是取决于编译器?

INT_MIN的绝对值大于INT_MAX的绝对值。操作-n产生的结果不在可表示的值范围内,当n == INT_MIN。当对有符号整数的算术运算产生一个不可表示的值时,程序的行为是未定义的。

相关内容

  • 没有找到相关文章

最新更新