如何编写单元测试以确保C中科学计算的数值准确性?

时间:2009-12-16 17:43:09

标签: c unit-testing

我正在探索连接C和R(使用R的.Call来提高速度)。我只使用C进行平凡的整数计算和文本处理应用程序,我从来不必担心浮点变量,下溢等问题。我可以为函数编写哪些测试来确保数值精度?

3 个答案:

答案 0 :(得分:3)

有关可能的边缘情况的详细概述,请参阅此Wikipedia article

然后,对于单元测试,请参阅The pitfalls of verifying floating-point computations

答案 1 :(得分:2)

要正确执行此类测试,您必须对代码中的所有浮点计算进行错误分析。为什么这很重要的典型例子包括寻找二次方程根的简单事物到解决疯狂递归关系(例如搜索“穆勒重现”)。

但是,进行此错误分析通常是非常重要且耗时的,而且通常是不可能的。在这种情况下,第二种最佳情况是拥有大量输入和正确的输出值,并在测试中使用它们。但这主要是一个鸡和蛋的问题,因为如何你找到了一些甚至稍微复杂的东西的正确值,除非在某种计算机上实际计算它们?

所以,实际的解决方案包括:

  1. Interval arithmetic,您可以使用数据结构来估计浮点计算所处的间隔。如果结果的间隔太大,您就会知道存在一些问题。有许多实现此类分析的实现,有关详细信息,请参阅this list。对于大型计算,此方法会很慢,但您可以尝试运行它以获取从实际数据中获取的一些代表性样本以获得想法。
  2. 如果您的编译器支持它,您可以使用不同的浮点舍入模式运行相同的代码。 C99对此进行了标准化,gcc支持它,所以你可能会很幸运。例如,请查看fesetround()fegetround()。我们的想法是,如果您的浮点计算稳定且准确,则不同的舍入模式应该会产生类似的输出。如果不同的舍入模式导致数字太不相同,则表示存在错误。遗憾的是,这种方法无法告诉您 错误,但这是第一步。此外,这个方法应该很快,除了你要为一个输入集运行代码四次这样的事实。

答案 2 :(得分:0)

我想:

  1. 准确性取决于参数 - 因此您可以测试一些值,以便稍后发现存在精度损失的其他值。
  2. 您可以测试极小增量相差的值,并查看算法是否保持精确度。
  3. 使用双打而不是浮动。
  4. 最后,您可以进行两次计算(通过第二次运行的最小增量来增加参数?),为每个操作选择最坏的情况,并查看您获得的答案范围。