在C++中进行数学运算时,浮点误差如何传播?

ksm*_*001 6 c c++ floating-point floating-accuracy floating-point-precision

假设我们已经声明了以下变量

float a = 1.2291;

float b = 3.99;

float 变量有精度6,(如果我理解正确的话)意味着计算机实际存储的数量与您想要的实际数量之间的差异将小于 10^-6

这意味着这两个ab有一定的误差小于10^-6

因此,在计算机内部a实际上可能1.229100000012123并且b可能是3.9900000191919

现在让我们说你有以下代码

float c = 0;
for(int i = 0; i < 1000; i++)
      c += a + b;
Run Code Online (Sandbox Code Playgroud)

我的问题是,

c最终结果的精度误差是否小于10^-6或等?

如果答案是否定的,那么我们怎么能真正知道这个精确度错误以及如果您按照自己的意愿和任何顺序应用任何类型的操作会发生什么?

Pas*_*uoq 6

浮点变量有精度6,(如果我理解正确的话)意味着计算机实际存储的数量与你想要的实际数量之间的差异将小于10 ^ -6

这意味着a和b都有一些小于10 ^ -6的错误

10 -6数字是将任意常数表示为浮点数时的相对精度的粗略度量.并非所有数字都以10 -6的绝对误差表示.例如,可以预期数字8765432.1大约表示单位.如果您至少有点幸运,那么当您将其表示为时,您将获得8765432 float.另一方面,1E-15f可以预期用绝对误差表示至多约10 -21.

所以在计算机内部实际上可能是1.229100000012123而b可能是3.9900000191919

不,对不起,它的工作方式不是你编写整个数字并为可能的错误添加六个零.可以通过从前导数字计算六个零来估计误差,而不是从最后一个数字计算.在这里,你可以期待1.22910012123或3.990000191919.

(实际上你会得到正好1.2290999889373779296875和3.9900000095367431640625.不要忘记表示错误可以是负数也可以是正数,因为它是第一个数字.)

现在让我们说你有以下代码[...]

我的问题是,

c最终结果的精度误差是否小于10 ^ -6?

号总绝对误差将全部用于表示误差的总和a,并b为每个使用过的千倍,再加上你做了2000和增补的错误.这是4000种不同的错误来源!其中许多将是相同的,其中一些将碰巧相互补偿,但最终结果可能不会达到10 -6相对准确度,更像是相对准确度为10 -5(建议不计算).