我遇到的问题是,当我对数组的值求和(这些都是正数,我通过打印数组的值进行验证)时,我最终得到一个负值。我的总和代码是:
int summcp = 0;
for (k = 0; k < SIMUL; k++)
{
summcp += mcp[k];
}
printf("summcp: %d.\n", summcp);`
任何有关此问题的提示都将受到赞赏。
答案 0 :(得分:2)
这闻起来像溢出的问题;您可能想要添加一个支票,如
for (k = 0; k < SIMUL && (INT_MAX - summcp > mcp[k]); k++ )
{
sumcp += mcp[k];
}
if (k < SIMUL)
{
// sum of all mcp values is larger than what an int can represent
}
else
{
// use summcp
}
如果您遇到溢出问题,可能需要使用更广泛的类型summcp
,例如long
或long long
。
修改强>
问题是有符号整数溢出的行为没有明确定义;根据您的平台是使用补码,二补码,符号幅度还是其他有符号整数表示,您会得到INT_MAX + 1
的不同结果。
就像我在下面的评论中所说,如果mcp
可以包含负值,那么您也应该添加一个下溢检查。
无论您使用哪种类型(int
,long
,long long
),都应该保留上下检查。
如果mcp
仅包含非负值,请考虑使用无符号类型作为总和。这样做的好处是 unsigned 整数溢出的行为是明确定义的,结果将是mcp
modulo UINT_MAX
(或{{}的所有元素的总和。 1}},或ULONG_MAX
等)。
答案 1 :(得分:2)
您正在调用未定义的行为。
由于整数变量只能包含有限的值范围,因此标准不会超出此范围。基本上任何事都可能发生。在您(以及最常见的)情况下,它只是包装其二进制表示。由于这用于负值,因此您将这样阅读。
要解决此问题,请使用summcp
的类型,该类型可以包含所有可能的值。另一种方法是检查下一次添加是否会溢出:
if ( summcp >= INT_MAX - mcp[k] ) {
// handle positive overflow
}
请注意,上述内容仅适用于mcp[k] >= 0
和正溢出。其他3个案件必须以不同方式处理。如果需要,通常最好,更快,更容易使用足够大的类型进行总和并稍后测试溢出。
不要试图添加和测试结果!由于整数溢出是未定义的行为,因此不适用于所有体系结构。
答案 2 :(得分:1)
声明变量summcp
,如
long long int summcp = 0;
答案 3 :(得分:1)
我认为你的最终输出超出了范围。为此,您必须将summcp
声明为long long int
long long int summcp = 0;
for (k = 0; k < SIMUL; k++)
{
summcp += mcp[k];
}
printf("summcp: %lld.\n", summcp);
int
变量如果超出其范围则抛出垃圾值。