【发布时间】:2013-10-13 04:00:46
【问题描述】:
出于验证的目的,我希望能够计算出在某些特定算术计算期间由于舍入到可表示值而导致的累积误差的合理严格上限。
假设我们有一个函数foo(),它声称要执行一些特定的算术计算。还假设有一个关于最大误差(由于舍入)的隐含保证,该保证源于所涉及的类型是 float 或 double 以及 foo() 执行计算的隐含(或声明)方式。
我希望能够验证来自foo() 的特定输入值集的结果,方法是还以跟踪累积的最坏情况错误的方式执行计算,然后检查两个结果是否与最终的最坏情况错误要求一样接近。
我想可以通过引入一个新的算术类 track_prec<T> 来做到这一点,该类将精度跟踪添加到基本浮点类型之一,然后让它取决于算术运算符的实现该类来计算每个子表达式的最坏情况错误。我的问题是我不知道如何在这些一般情况下计算这些最坏情况的错误:
// T = float or double
template<class T> class track_prec {
public:
T value;
T ulp; // http://en.wikipedia.org/wiki/Unit_in_the_last_place
track_prec& operator+=(const track_prec& v)
{
value += v.value;
ulp = ???; // How to do this? And what about -=, *=, and /=?
}
friend bool operator==(T, const track_prec&)
{
// Exactly how should this comparison be done?
}
};
例如,假设foo() 是对一系列数字的简单求和。那么我们可以使用track_prec<T>如下:
std::vector<T> values { 0.4, -1.78, 1.3E4, -9.29E3, ... };
CHECK_EQUAL(std::accumulate(values.begin(), values.end(), track_prec<T>()),
foo(values.begin(), values.end()));
当然,任何形式的帮助都是受欢迎的,但是指向免费和工作代码的指针会非常好。
我找到了有关该主题的这些链接,但它们似乎无法直接回答我的问题。
【问题讨论】:
-
区间算术很有吸引力,但它并没有大受欢迎。它几乎没有硬件支持。大多数机器要么不支持必要的舍入模式,要么为切换舍入模式强加高执行时间成本。大多数情况下,当需要误差范围时,它们会由人工针对特定情况进行计算或通过各种方式进行估计。
-
好吧,不过,就我而言,性能不是问题,因为只有验证码会进行精确跟踪。但是你知道任何可以自动计算错误界限的 C/C++ 实现吗?
标签: c++ floating-point verification floating-point-precision