如果有的话,可以对浮点计算的准确性/精确度提出什么要求?

时间:2010-02-15 02:07:47

标签: c++ floating-point ieee-754

我正在开发一个执行大量浮点计算的应用程序。我们在Intel x86上使用VC ++,具有双精度浮点值。我们声称我们的计算精确到 n 十进制数字(现在7,但试图声称15)。

当我们的结果略有变化时(由于代码重构,清理等),我们会花费大量精力来验证我们针对其他来源的结果。我知道有许多因素影响整体精度,例如FPU控制状态,编译器/优化器,浮点模型以及操作本身的总体顺序(即算法本身),但考虑到固有的不确定性在FP计算中(例如,0.1无法表示),对所有计算声明任何特定程度的精确度似乎无效。

我的问题是:在没有进行任何分析(例如间隔分析)的情况下,对FP计算的准确性做出任何声明是否有效?如果是这样,可以提出什么要求以及为什么?

修改

因此,假设输入数据精确到 n 小数位,那么在使用双精度的情况下,是否可以保证任意计算的结果?例如,如果输入数据有8位有效小数,输出将至少有5位有效小数......?

我们正在使用数学库,并且不知道他们可能会或可能不会做出任何保证。我们使用的算法不一定以任何方式分析精度。但即使给定一个特定的算法,实现也会影响结果(例如,只改变两个加法运算的顺序)。使用双精度时是否有任何固有的保证?

另一个编辑:

我们根据经验验证我们的结果与其他来源。那么,当我们达到10位数的准确度时,我们才会幸运吗?

7 个答案:

答案 0 :(得分:7)

与所有这些问题一样,我只需回答文章What Every Computer Scientist Should Know About Floating-Point Arithmetic。对于你所谈论的工作类型来说,它绝对是必不可少的。

答案 1 :(得分:6)

简答:否。

原因:您是否证明了(是的证明)您不会随着时间的推移而失去任何精确度?你确定吗?您是否了解您用于超越函数的任何库函数的内在精度?你有没有计算加性误差的极限?如果您使用的是迭代算法,那么在退出时,您是否知道它已融合的程度如何?这个东西很难。

答案 2 :(得分:5)

除非您的代码仅使用IEEE 754(+, - ,*,/和平方根)中指定的基本操作,否则您甚至不知道每次调用控件之外的库函数的精度损失(三角函数,exp / log,...)介绍。基本5之外的函数不能保证在1ULP处精确,并且通常不精确。

你可以进行实证检验,但这就是它们的存在......经验。不要忘记关于软件的EULA没有保修的部分!

如果您的软件对安全至关重要,并且没有调用库实现的数学函数,那么您可以考虑使用http://www-list.cea.fr/labos/gb/LSL/fluctuat/index.html。但只有关键软件才值得付出努力,并有机会适应此工具的分析约束。

在您编辑之后,您似乎主要关注您的编译器在后面做事情。这是一种自然的恐惧(因为就像数学函数一样,你无法控制)。但这不太可能成为问题。您的编译器可能会以比您要求的更高的精度进行计算(当您要求提供64位双精度数或64位双精度数时,要求使用32位浮点数时)。这是C99标准允许的。在舍入到最接近的情况下,这可能会引入双舍入误差。但是你只有1ULP输了,很少你不用担心。这可能会引起令人费解的行为,如:

float x=1.0;
float y=7.0;
float z=x/y;
if (z == x/y) 
...
else
... /* the else branch is taken */

但是当您在浮点数之间使用==时,您一直在寻找麻烦。

如果您的代码有意取消,例如Kahan的求和算法:

d = (a+b)-a-b;

并且编译器将其优化为d=0;,您就遇到了问题。是的,这种优化“好像浮动操作是关联的”已经在一般的编译器中看到了。 C99允许。但我认为情况已经好转了。编译器作者已经越来越意识到浮点的危险,并且不再试图如此积极地进行优化。另外,如果您在代码中执行此操作,则不会问这个问题。

答案 3 :(得分:2)

鉴于您的计算机,编译器,运行时库和操作系统供应商未就浮点准确性做出任何此类声明,您应该将其作为组的警告如果客户将你告上法庭,应该对提出可能受到严厉审查的索赔持谨慎态度。

如果不对整个系统进行正式验证,我会避免这种说法。我研究的是具有间接人类安全意义的科学软件,所以我们过去一直在考虑这些问题,而且我们没有做出这类索赔。

你可以对双(长度)浮点计算的精度做出无用的声明,但它基本上没用。

参考:The pitfalls of verifying floating-point computations来自ACM编程语言与系统交易30,3(2008)12

答案 4 :(得分:1)

不,你不能提出这样的要求。如果您想这样做,则需要执行以下操作:

  • 聘请数值计算专家来分析您的算法。
  • 要么让你的库和编译器供应商向所述专家打开他们的资源进行分析,要么让他们签署硬语义和错误界限。

双精度浮点通常带有大约15位的十进制精度,但是有太多的方法可能会丢失部分或全部精度,这对于a非专家诊断,提出任何你想要声称的声明。

有一些相对简单的方法可以保持运行错误界限,让您可以对任何特定的计算进行准确性声明,但是对使用您的软件执行的所有计算的准确性做出声明是一个更高的顺序

答案 5 :(得分:0)

Intel CPU上的双精度数略好于15位有效数字(十进制)。

简单计算的重要错误在n / 1.0e15的大球中,其中n是您正在使用的数字的数量级。我怀疑英特尔有关于基于CPU的FP计算准确性的规范。

通常会记录库函数(如cos和log)的潜在错误。如果没有,你可以查看源代码(例如thr GNU源代码)并计算它。

您可以像计算手动计算一样计算计算的误差线。

一旦你这样做,你就可以通过明智地计算计算来减少错误。

答案 6 :(得分:0)

由于您似乎关心任意计算的准确性,因此您可以尝试以下方法:使用different rounding modes运行代码进行浮点计算。如果结果非常接近,那么你可能还可以。如果结果不是很接近,你需要开始担心。

结果的最大差异将为您提供计算准确性的下限。

相关问题