繁体   English   中英

如何在+,-,*和/中舍入错误后计算浮点精度?

[英]How to calculate floating-point precision after round-off errors in +, -, *, and /?

出于验证的目的,我希望能够在某些特定的算术计算过程中由于四舍五入到可表示的值而对累积误差计算出一个合理的严格上限。

假设我们有一个函数foo()声称可以执行一些特定的算术运算。 还假定存在一个隐式保证,即所涉及的类型为floatdouble以及由于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()));

当然,欢迎任何形式的帮助,但是指向自由代码和有效代码的指针将非常有用。

我在主题上找到了这些链接,但是它们似乎并不能直接回答我的问题。

跟踪浮点计算精度的最简单方法是间隔算术 它不需要IEEE 754算术运算,只需要将计算切换为向上或向下舍入即可,这样,在每一步中,所计算区间的边界就包含了如果使用实数进行相同计算就可以得到的所有实数。算术。

您应该能够找到许多现有的区间算术实现。

在任何给定步骤中计算的准确性是在该步骤中计算的间隔的宽度。

注意常数:如果您希望近似πx,则需要将包含π的浮点间隔乘以x的间隔。 如果将x的间隔乘以3.1415926535897932表示的倍数,则会得到x乘以该倍数的误差(既不等于π也不等于3.1415926535897932)。 在问题代码中,常数0.4表示“最接近0.4的双精度数”。 如果需要有理数4/10,请使用区间为3.9999999999999997e-014.0000000000000002e-01分别表示两个双精度值的区间。

在此处查看如何实施错误跟踪。 https://github.com/Esri/geometry-api-java/blob/master/src/main/java/com/esri/core/geometry/ECoordinate.java

基本思想是浮点算术结果将接近正确值+-0.5 * DBL_EPSILON *值。 这样您就可以跟踪和累积它。 上面链接中的代码将计算a + b的绝对误差为

err(a+b) = err(a) + err(b) + DBL_EPSILON * abs(a + b). 

假设:IEEE 754双浮点运算使用保护位。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM