各种浮动值的epsilon

时间:2012-08-09 12:53:47

标签: c floating-point-precision epsilon

FLT_MIN常数最接近零。如何最接近some number值?

举个例子:

float nearest_to_1000 = 1000.0f + epsilon;
// epsilon must be the smallest value satisfying condition:
// nearest_to_1000 > 1000.0f

我更喜欢不使用特殊功能的数字公式。

1 个答案:

答案 0 :(得分:2)

警告:在处理其他答案时,在此代码中发现了错误。我希望稍后更新。与此同时,它失败了一些涉及次正规的值。

C在<math.h>标题中为此提供了一个函数。 nextafterf(x, INFINITY)x之后的下一个可表示的值,朝向INFINITY的方向。

但是,如果您更愿意自己动手​​:

以下为单精度(浮点数)返回您寻找的epsilon,假设为IEEE 754。

#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.
*/
float ULP(float q)
{
    // SmallestPositive is the smallest positive floating-point number.
    static const float SmallestPositive = FLT_EPSILON * FLT_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 float Scale = 0.75 * FLT_EPSILON;

    q = fabs(q);

    return fmax(SmallestPositive, q - (q - q * Scale));
}

以下内容返回传递值后浮点数中可表示的下一个值(将-0和+ 0视为相同)。

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


/*  Return the next floating-point value after the finite value 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.
*/
float NextAfter(float q)
{
    // SmallestPositive is the smallest positive floating-point number.
    static const float SmallestPositive = FLT_EPSILON * FLT_MIN;

    /*  Scale is .625 ULP, so multiplying it by any significand in [1, 2)
        yields something in [.625 ULP, 1.25 ULP].
    */
    static const float Scale = 0.625 * FLT_EPSILON;

    return q + fmax(SmallestPositive, fabs(q)*Scale);
}