数组中的正值之和在c程序中给出否定结果

时间:2015-07-01 13:07:12

标签: c arrays

我遇到的问题是,当我对数组的值求和(这些都是正数,我通过打印数组的值进行验证)时,我最终得到一个负值。我的总和代码是:

int summcp = 0;
for (k = 0; k < SIMUL; k++)
{
    summcp += mcp[k];
}
printf("summcp: %d.\n", summcp);`

任何有关此问题的提示都将受到赞赏。

4 个答案:

答案 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,例如longlong long

修改

问题是有符号整数溢出的行为没有明确定义;根据您的平台是使用补码,二补码,符号幅度还是其他有符号整数表示,您会得到INT_MAX + 1的不同结果。

就像我在下面的评论中所说,如果mcp可以包含负值,那么您也应该添加一个下溢检查。

无论您使用哪种类型(intlonglong 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变量如果超出其范围则抛出垃圾值。