3

如果我这样做,在 C++ 中:

__int64 var = LLONG_MIN;
__int64 var2 = -var;
cout << "var: "<< var << endl;
cout << "var2: "<< var2 << endl;

我得到的输出是:

var: -9223372036854775808
var2: -9223372036854775808

标准的哪一部分涵盖了这一点?我假设它是有符号整数溢出。这是使用 g++ (GCC) 4.7.2 编译的。

我有一个减法函数,我正在编写一个加法函数,我想我可以这样做: add( someobj &obj, long long num ) { subtract( obj, -num ); }. 如果不是 LLONG_MIN,我认为这会起作用。

4

2 回答 2

9

它确实是整数溢出,并且是二进制补码的产物

在你的实现中,是LLONG_MIN十六进制的(我将使用这个十六进制表示法,因为它更容易看到这些位发生了什么)。-92233720368547758080x8000000000000000

当您-LLONG_MIN在使用二进制补码的系统上进行计算时,在引擎盖下您首先进行按位非(yielding 0x7FFFFFFFFFFFFFFF == LLONG_MAX)然后添加 1 溢出有符号整数并返回0x8000000000000000 == LLONG_MIN

请注意,有符号整数溢出是未定义的行为,因此不能保证它在每个 C++ 实现上的行为都会一致。

于 2013-09-08T19:30:38.297 回答
0

虽然另一个答案是正确的,但我认为它不能解释这个直观的一面:

LLONG_MIN ==  -2^63      == -9223372036854775808
LLONG_MAX ==   2^63 - 1  ==  9223372036854775807

我试图考虑使用 LLONG_MIN 作为某事的特例,但后来我记得对于 c++ 有符号整数类型,最小值总是比最大​​值离 0 更远 1(有趣的是,它们中的每一个,从字节加倍,以-...8和结尾+...7!)。

所以,我当时很好奇如果你否定最低值会发生什么,因为在正值领域没有对应的值;而且,唉,它被算作整数溢出(-9223372036854775808 == 9223372036854775808 > 9223372036854775807),因此它溢出了1(9223372036854775807 + 1),导致我们回到...... -9223372036854775808


代码:

#include <iostream>
#include <climits>
using namespace std;

int main() {
  long long l1 = LLONG_MIN;
  long long l2 = -l1; //Equivalent to l1.
  long long l3 = l1 - 1;
  long long l4 = l3 + 1;
  cout << l1 << "\n";
  cout << l2 << "\n";
  cout << l3 << "\n";
  cout << l4 << "\n";

  return 0;
}

输出:

-9223372036854775808
-9223372036854775808
 9223372036854775807
-9223372036854775808
于 2017-10-19T01:14:13.253 回答