在计算平均值时得到负数,怀疑是整数溢出
我是大一新生。
我正在写一个C 程序,用来计算整数数组的平均值。数组元素比较大,结果有时会变成负数,或者是明显错误的值。我怀疑是整数溢出,但不确定。这是我的代码:
#include <stdio.h>
int main() {
int arr[] = {2000000000, 2000000000, 2000000000};
int n = 3;
int sum = 0;
for (int i = 0; i < n; i++) {
sum += arr[i];
}
printf("Average = %d\n", sum / n);
return 0;
}
输出是一个负数。我的问题是:
- 这一定是由整数溢出引起的吗?
- 如何在不使用double的情况下修正代码,以正确计算大数的平均值?
解决方案
是的——这确实是由 整数溢出 引起的。
但在大多数系统上,普通的 int 是一个32位带符号整数:范围是 -2147483648到 2147483647。
因此 6000000000 超过了最大值,发生溢出,导致结果为一个错误的负数。
使用更大的整数类型,例如 long long。
备选方案
如果元素个数提前已知,则平均值可以用以下公式表示:
(n*div1 + rem1 + n*div2 + rem2 + ..)/n = (div1 + div2 + ..) + (rem1 + rem2 + ..)/n
需要把所有值相加:div = div1 + div2 + .. 和 rem = rem1 + rem2 + ..。div 不会溢出,但如果 n 的值过大,rem 可能会溢出。rem 的最大可能值是 (n - 1) * n。 (For INT_MAX = 2147483647, the value of n should not exceed 46341.) 如果条件 n - 1 <= INT_MAX / n 满足,则平均值的计算不需要考虑 rem 的可能溢出,否则应按照 0___________ 的建议来计算平均值。
#include <stdio.h>
#include <limits.h>
int main() {
int arr[] = {2147483647, 2147483647, 2147483647};
int n = sizeof arr / sizeof *arr;
int div = 0, rem = 0;
if (n - 1 <= INT_MAX / n) {
for (int i = 0; i < n; i++) {
div += arr[i] / n;
rem += arr[i] % n;
}
div += rem / n;
}
else {
for (int i = 0; i < n; i++) {
div += arr[i] / n;
rem += arr[i] % n;
div += rem / n;
rem %= n;
}
}
printf("Average = %d\n", div);
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。