我有两个大小接近 1000 的整数向量,我要做的是检查这两个向量的平方整数之和是否相同。所以我写了以下代码:
std::vector<int> array1;
std::vector<int> array2;
... // initialize array1 and array2, and in the experiment all elements
    // in the two vectors are the same but the sequence of elements may be different.
    // For example: array1={1001, 2002, 3003, ....} 
   //               array2={2002, 3003, 1001, ....}
assert(array1.size() == array2.size());
float sum_array1 = 0;
float sum_array2 = 0;
for(int i=0; i<array1.size(); i++)
       sum_array1 +=array1[i]*array1[i];
for(int i=0; i<array2.size(); i++)
       sum_array2 +=array2[i]*array2[i];
我希望这sum_array1应该等于sum_array2,但实际上在我的应用程序中我发现它们不同sum_array1 = 1.2868639e+009而sum_array2 = 1.2868655e+009. 我接下来所做的是更改类型sum_array1和sum_array2双类型,如下面的代码所示:
 double sum_array1 = 0;
    double sum_array2 = 0;
    for(int i=0; i<array1.size(); i++)
           sum_array1 +=array1[i]*array1[i];
    for(int i=0; i<array2.size(); i++)
           sum_array2 +=array2[i]*array2[i];
这个时间  sum_array1等于sum_array2 sum_array1=sum_array2=1286862225.0000000。我的问题是为什么它会发生。谢谢。
浮点值的大小是有限的,因此只能表示具有有限精度的实数值。当您需要比它们可以存储的精度更高的精度时,这会导致舍入错误。
特别是,当将一个小数(例如您正在求和的数)与一个大得多的数(例如您的累加器)相加时,与小数相比,精度损失可能相当大,从而产生显着的误差;并且错误会因订单而异。
通常,float具有 24 位精度,对应大约 7 个小数位。您的累加器需要 10 个小数位(大约 30 位),因此您会遇到这种精度损失。通常,double有 53 位(大约 16 位小数),因此您的结果可以准确表示。
64 位整数可能是这里的最佳选择,因为所有输入都是整数。使用整数可避免精度损失,但如果输入过多或过大,则会带来溢出的危险。
如果不能使用足够宽的累加器,为了最小化错误,您可以对输入进行排序,以便首先累加最小值;或者您可以使用更复杂的方法,例如Kahan summation。
| 归档时间: | 
 | 
| 查看次数: | 1841 次 | 
| 最近记录: |