gpt4 book ai didi

c++ - 计算数组的平均值 C++

转载 作者:行者123 更新时间:2023-11-27 22:36:54 33 4
gpt4 key购买 nike

当我试图用两种方法计算一个数组的均值时,我遇到了一个问题。下面是代码:

float sum1, sum2, tmp, mean1, mean2;
double sum1_double, sum2_double, tmp_double;
int i, j;
int Nt=29040000; //array size
int piecesize=32;
int Npiece=Nt/piecesize;
float* img;
float* d_img;
double* img_double;
img_double = (double*)calloc(Nt, sizeof(double));
cudaHostAlloc((void**)&img, sizeof(float)*Nt, cudaHostAllocDefault);
cudaMalloc((void**)&d_img, sizeof(float)*Nt);
...
//Some calculation is done in GPU and the results are stored in d_img;
...
cudaMemcpy(img, d_img, Nt*sizeof(float), cudaMemcpyDeviceToHost);
for (i=0;i<Nt;i++) img_double[i]=(double)img[i];

//Method 1
sum1=0;
for (i=0;i<Nt;i++)
{ sum1 += img[i]; }

sum1_double=0;
for (i=0;i<Nt;i++)
{ sum1_double += img_double[i]; }

//Method 2
sum2=0;
for (i=0;i<Npiece;i++)
{ tmp=0;
for (j=0;j<piecesize;j++)
{ tmp += img[i*piecesize+j];}
sum2 += tmp;
}

sum2_double=0;
for (i=0;i<Npiece;i++)
{ tmp_double=0;
for (j=0;j<piecesize;j++)
{ tmp_double += img_double[i*piecesize+j];}
sum2_double += tmp_double;
}

mean1=sum1/(float)Nt;
mean2=sum2/(float)Nt;
mean1_double=sum1_double/(double)Nt;
mean2_double=sum2_double/(double)Nt;

cout<<setprecision(15)<<mean1<<endl;
cout<<setprecision(15)<<mean2<<endl;
cout<<setprecision(15)<<mean1_double<<endl;
cout<<setprecision(15)<<mean2_double<<endl;

输出:

132.221862792969
129.565872192383
129.565938340543
129.565938340543

两种方法得到的结果,mean1=129.6,mean2=132.2,有显着差异。我可以知道为什么吗?

提前致谢!

最佳答案

原因是浮点运算不精确。当您累积整数时,当 abs(value) 变得大于 224 时, float 变得不精确(我在这里假设 IEEE-754 32 位)。例如,float 无法精确存储 16777217(它会变成 16777216 或 16777218,具体取决于舍入方式)。

假设您的第二次计算更精确,因为单独的 tmp 累加导致精度损失较小。

将您的 sum1sum2tmp 变量更改为 long long int,希望您会得到两次计算的结果相同。

注意:我假设您的 img 存储整数数据。如果它存储 float ,则没有简单的方法可以完美地解决这个问题。一种方法是对 sum1sum2tmp 使用 double 而不是 float .差异会存在,但会小很多。还有一些技术可以比简单求和更精确地累加 float。喜欢Kahan Summation .

关于c++ - 计算数组的平均值 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53141551/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com