【发布时间】:2020-10-21 12:18:13
【问题描述】:
我创建了以下代码来寻找硬币问题的答案。这涉及找到给定 k 面额的硬币的最小数量(其中每个这样的硬币都是无限供应的)以形成目标总和 n。特别是我调查了k=5,面额={2,3,4,5,6}和目标总和n=100的情况。
代码:
#include<iostream>
#include<algorithm>
using namespace std;
int coins[5] = {2,3,4,5,6};
int values[101];
int n=100;
int k=5;
int INF = INT_MAX;
int main()
{
for (int x=1;x<=n;x++)
{
values[x] = INF;
for (int j=1;j<=k;j++)
{
if (x-coins[j-1]>=0)
{
values[x] = min(values[x],values[x-coins[j-1]]+1);
}
}
}
cout<<values[100];
return 0;
}
我收到的此代码的输出是-2147483632。显然一定会发生某种溢出,所以我决定输出INF+1。我得到了INT_MIN 作为答案。但我也记得,在输出一些超出 int 范围的数字时,通常不会出现这样的问题。
我决定输出1e11,令我惊讶的是答案仍然是1e11。为什么会这样,请帮忙。
【问题讨论】:
-
有符号整数溢出调用未定义行为
-
有符号整数溢出是未定义的,在实践中它可能仍然有效,这就是你的实验没有帮助解决问题的原因。看起来有效的 UB 仍然是 UB
-
也许不是你的问题,但你应该设置
values[0] = 0; -
1e11的类型为double,并且是一个可以由double完美表示的值。 -
@Damien -- 因为它是在文件范围内定义的,所以
values中的所有元素都设置为 0。将values[0]显式设置为 0 不会改变任何内容。
标签: c++ c++14 integer-overflow