2

给定两个浮点值(fLowfHigh),您如何计算两个连续值之间的最大或最大步幅/间隙?

例如:

在答案的范围内16777217f20000000f2,因为值有效地四舍五入到最接近的两个。

将其推广到任意范围让我摸不着头脑——有什么建议吗?

干杯,

这应该是语言中立的,但我使用的是 C#(我认为它符合 IEEE-754)。

4

2 回答 2

6

这是在 C 中。它需要一些 IEEE 754 行为,用于舍入等。对于 IEEE 754 64 位二进制 ( double),SmallestPositive为 2 -1074 ,约 4.9406564584124654417656879286822137236505980261e - 324,DBL_EPSILON 为 2 -52,2.220446049250313080847625-1368640626333 对于 32 位二进制 ( float),在它们出现的任何地方更改DBLtoFLTdoubleto (以及to和to ,尽管它应该在没有这些更改的情况下工作)。然后是 2 -149,大约是 1.401298464324817070923729583289916131280261941876515771757068283889791e-45,FLT_EPSILON 是 2 -23, 1.1920928955078125e-07。floatfabsfabsffmaxfmaxfSmallestPositive

对于两个值之间的间隔,最大的步长当然是具有较大幅度的端点处的步长。(如果该端点恰好是 2 的幂,则从该点到下一个点的步长不会出现在区间本身中,因此这是一种特殊情况。)

#include <float.h>
#include <math.h>

/*  Return the ULP of q.

    This was inspired by Algorithm 3.5 in Siegfried M. Rump, Takeshi Ogita, and
    Shin'ichi Oishi, "Accurate Floating-Point Summation", _Technical Report
    05.12_, Faculty for Information and Communication Sciences, Hamburg
    University of Technology, November 13, 2005.
*/
double ULP(double q)
{
    // SmallestPositive is the smallest positive floating-point number.
    static const double SmallestPositive = DBL_EPSILON * DBL_MIN;

    /*  Scale is .75 ULP, so multiplying it by any significand in [1, 2) yields
        something in [.75 ULP, 1.5 ULP) (even with rounding).
    */
    static const double Scale = 0.75 * DBL_EPSILON;

    q = fabs(q);

    return fmax(SmallestPositive, q - (q - q * Scale));
}
于 2013-03-20T23:05:27.227 回答
1

嗯,机器精度,顾名思义,实际上可能通常取决于机器,甚至取决于编译器。因此,要真正确定您通常必须编写一个实际测试正在发生的事情的程序。

但是,我怀疑您确实在寻找一些方便的公式,您可以使用这些公式来估算给定间隔内的最大距离。关于机器 epsilon的 Wikipedia 文章对这个主题给出了非常好的概述,我在下面主要引用了这个来源。

设为s您的浮点表示的机器 epsilon(即,在标准浮点数的情况下约为 2^(-24)),则归一化x与其邻居之间的最大间距为2*s*|x|. 规范化这个词在这里非常重要,我什至不会尝试考虑非规范化数字的情况,因为这是事情变得非常糟糕的地方......

也就是说,在您的特定情况下,h您建议的间隔中的最大间距由 给出h = 2*s*max(|fLow|, |fHigh|)

于 2013-03-20T23:08:24.233 回答