使用OpenMP计算数组均值时为何得到错误结果?
OpenMP并行计算数组均值错误原因及修正
我在使用OpenMP并行计算数组均值时得到了错误结果,以下是我的代码:
#include <stdio.h> #include <omp.h> #define N 5 int X[N]; int main() { int num = 0; int moy = 0; // Initialize the array (you should populate it as needed) for (int i = 0; i < N; i++) { X[i] = i * 2; // Example initialization } // Calculate the average #pragma omp parallel for reduction(+:moy) for (int i = 0; i < N; i++) { moy += X[i] / N; } // Count elements greater than the average #pragma omp parallel for reduction(+:num) for (int i = 0; i < N; i++) { if (X[i] > moy) { num++; } } printf("%d\n", num); return 0; }添加打印语句后得到如下输出:
均值(moy):2
数组X的元素:0 2 4 6 8
大于均值的元素数量:3
请问为何会出现这种错误结果?
错误原因分析
1. 整数除法的计算顺序错误
你的均值计算逻辑是先对每个元素做整数除法再累加,而正确的均值计算应该是先累加所有元素的总和,再做除法。
对于数组[0,2,4,6,8],每个元素除以5(N=5)的整数结果是:
- 0/5 = 0
- 2/5 = 0
- 4/5 = 0
- 6/5 = 1
- 8/5 = 1
累加后得到0+0+0+1+1=2,这就是你得到错误均值2的原因,而正确的总和是20,均值应为20/5=4。
2. 数据类型导致的精度丢失(次要)
moy被定义为int类型,即使修正计算顺序,若数组总和不能被N整除,整数除法也会直接丢弃小数部分。比如如果数组总和是21,正确均值是4.2,但整数除法会得到4,可能影响后续的比较逻辑。
修正方案
调整均值计算的顺序,先累加所有元素的总和,再除以N;同时建议使用浮点类型存储均值,避免精度丢失:
#include <stdio.h> #include <omp.h> #define N 5 int X[N]; int main() { int num = 0; int sum = 0; // 先存总和 double moy = 0.0; // 用浮点类型存均值 // 初始化数组 for (int i = 0; i < N; i++) { X[i] = i * 2; } // 并行累加总和 #pragma omp parallel for reduction(+:sum) for (int i = 0; i < N; i++) { sum += X[i]; } // 计算均值 moy = (double)sum / N; // 统计大于均值的元素数量 #pragma omp parallel for reduction(+:num) for (int i = 0; i < N; i++) { if (X[i] > moy) { num++; } } printf("均值(moy):%.1f\n", moy); printf("大于均值的元素数量:%d\n", num); return 0; }
修正后的输出会是:
均值(moy):4.0
大于均值的元素数量:2
这符合预期结果。
内容的提问来源于stack exchange,提问作者M V
相关产品推荐
相关产品推荐

