C++ 关于浮点计算的准确性/精度,可以提出哪些主张(如有)?

C++ 关于浮点计算的准确性/精度,可以提出哪些主张(如有)?,c++,floating-point,ieee-754,C++,Floating Point,Ieee 754,我正在开发一个可以进行大量浮点计算的应用程序。我们在英特尔x86上使用VC++和双精度浮点值。我们声称我们的计算精确到n位小数(目前为7位,但尝试声明为15位) 当我们的结果发生轻微变化时(由于代码重构、清理等),我们会花费大量精力对照其他来源验证我们的结果。我知道很多因素影响整体精度,如FPU控制状态、编译器/优化器、浮点模型和整体操作顺序本身(即算法本身),但鉴于FP计算中固有的不确定性(例如,无法表示0.1),对于所有计算,要求任何特定精度似乎都是无效的 我的问题是:在不进行任何分析(如区

我正在开发一个可以进行大量浮点计算的应用程序。我们在英特尔x86上使用VC++和双精度浮点值。我们声称我们的计算精确到n位小数(目前为7位,但尝试声明为15位)

当我们的结果发生轻微变化时(由于代码重构、清理等),我们会花费大量精力对照其他来源验证我们的结果。我知道很多因素影响整体精度,如FPU控制状态、编译器/优化器、浮点模型和整体操作顺序本身(即算法本身),但鉴于FP计算中固有的不确定性(例如,无法表示0.1),对于所有计算,要求任何特定精度似乎都是无效的

我的问题是:在不进行任何分析(如区间分析)的情况下,就FP计算的准确性提出任何主张是否有效?如果是,可以提出什么索赔,为什么

编辑:

因此,假设输入数据精确到小数点后n位,那么,如果使用双精度,是否可以保证任意计算的结果?例如,如果输入数据有8位有效十进制数字,则输出将至少有5位有效十进制数字

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

另一次编辑:


我们确实根据其他来源对我们的结果进行了实证验证。那么,当我们达到,比如说,10位数的准确度时,我们是不是就幸运了呢?

对于所有这些问题,我只能简单地用这篇文章来回答。这对于你所谈论的工作类型来说是绝对必要的。

简短回答:


原因:您是否已经证明(是的,已经证明)在进行过程中不会丢失任何精度?你确定吗?你知道你用于超越函数的库函数的内在精度吗?你计算过加性误差的极限吗?如果您使用的是迭代算法,您知道退出时它收敛得有多好吗?这东西很硬

除非您的代码仅使用IEEE 754(+、-、*、/和平方根)中指定的基本操作,否则您甚至不知道对您控制之外的库函数(三角函数、exp/log等)的每次调用会带来多少精度损失。basic 5之外的功能不保证在1ULP时精确,通常也不精确

你可以做经验性的检查,但那是他们保持的。。。经验主义的。不要忘记在您的软件的EULA中没有保证的部分

如果你的软件是安全关键的,并且没有调用库实现的数学函数,你可以考虑。但只有关键软件值得付出努力,并有机会适应此工具的分析约束

在编辑之后,您似乎最关心的是编译器在您的后面做的事情。这是一种自然的恐惧(因为就像数学函数一样,你无法控制)。但这不太可能是问题所在。编译器的计算精度可能高于您要求的精度(当您要求64位双精度时为80位扩展,当您要求32位浮点时为64位双精度)。这是C99标准允许的。在四舍五入到最近的情况下,这可能会导致双舍入误差。但这只是你正在失去的1点,而且是如此罕见,以至于你不必担心。这可能会导致令人困惑的行为,如:

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不允许的。但我认为情况已经有所好转。编译器的作者们已经越来越意识到浮点运算的危险性,不再试图如此积极地进行优化。另外,如果您在代码中这样做,您就不会问这个问题。

鉴于您的机器、编译器、运行时库和操作系统供应商没有对浮点精度提出任何此类声明,你应该将此视为一个警告,即如果客户将你告上法庭,你的团队应该对可能受到严厉审查的索赔保持警惕

如果不对整个系统进行正式验证,我将避免这种说法。我研究的是具有间接人类安全含义的科学软件,所以我们过去已经考虑过这样的事情,我们没有提出这样的主张。 您可以对双(长)浮点计算的精度提出无用的主张,但这基本上毫无价值


参考:来自编程语言和系统上的ACM事务30,3(2008)12

英特尔CPU上的双精度数字略高于15位有效数字(十进制)

简单计算的潜在误差为n/1.0e15,其中n是您正在处理的数字的数量级。我怀疑英特尔对基于CPU的FP计算的准确性有规定

通常会记录库函数(如cos和log)的潜在错误。如果没有,您可以查看源代码co