我在c++中遇到了一个奇怪的错误,其中一个计算2个小整数加法的语句溢出到一个长值中

I ran into a weird bug in c++ where a statement calculating an addition of 2 small integers overflow into a long long value

本文关键字:一个 整数 溢出 2个 语句 错误 遇到 c++ 我在 计算      更新时间:2023-10-16

我最近遇到了一个我无法理解的奇怪的C++错误。这是我的代码:

#include <bits/stdc++.h>
using namespace std;
typedef vector <int> vi;
typedef pair <int, int> ii;
#define ff first
#define ss second
#define pb push_back
const int N = 2050;
int n, k, sum = 0;
vector <ii> a;
vi pos;
int main (void) {
cin >> n >> k;
for (int i = 1; i < n+1; ++i) {
int val;
cin >> val;
a.pb(ii(val, i));
}
cout << a.size()-1 << " " << k << " " << a.size()-k-1 << "n";
}

当我试用测试时:

5 5
1 1 1 1 1

它返回:

4 5 4294967295

但当我把声明从改为

int n, k, sum = 0;

至:

long long n, k, sum = 0;

然后程序返回正确的值:

4 5 -1

我不明白为什么程序会这样,因为-1不应该超过一个整数值。有人能向我解释一下吗?我真的很感激你的帮助。

感谢

显然,在您的机器上,size_t是32位整数,而long long是64位。size_t总是一个无符号类型,所以您得到:

cout << a.size()      -   1
//        ^ unsigned      ^ promoted to unsigned
//      output as uint32_t
//                ^ (!)
a.size() - k - 1
// ^ promoted to long long, as of smaller size!
// -> overall expression is  int64_t
//                          ^ (!)

如果size_t也是64位的,则打印的两个值不会有任何差异(可能是18446744073709551615(,因为有符号的long long k(int64_t(会升级为无符号的(uint64_t(。

请注意,static_cast<UnsignedType>(-1)总是计算(根据C++转换规则(为std::numeric_limits<UnsignedType>::max()

关于size_t的旁注:它被定义为一个无符号整数类型,其大小足以容纳您可以在系统上为对象分配的最大大小,因此以位为单位的大小取决于硬件,最终与内存地址总线的以位为单元的大小相关(二的一次方不小于(。

vector::size返回size_t(unsigned(,表达式a.size()-k-1的计算结果为无符号类型,因此最终会出现下溢。

相关文章: