为什么 h = FLT_MIN 的差商总是等于 0? FLT_MIN 是否迷失在浮动错误中?

问题描述 投票:0回答:1

我正在尝试使用差商找到贝塞尔曲线的斜率。差商为:

( f(x + h) - f(x) ) / h
在微积分中,我们通常使用极限,假设 h 无限小并评估公式。在这里,我想做类似的事情,使 h 等于 FLT_MIN 或 FLT_TRUE_MIN,这应该是最小的正浮点值。然而,当我运行 getApproxNormal(0.5f) 时,我只是得到 0,而不是正常值的大致范围。

// _p0 = (0,0)
// _p1 = (0,100)
// _p2 = (100,100)

typedef sf::vector2f Vec2f;
getBezierPoint(float t)
{
    float x = powf(1 - t, 2) * _p0.x + 2 * (1 - t) * t * _p1.x + std::pow(t, 2) * _p2.x;
    float y = powf(1 - t, 2) * _p0.y + 2 * (1 - t) * t * _p1.y + std::pow(t, 2) * _p2.y;
    return Vec2f(x, y);
}
getApproxNormal(float t)
{
    Vec2f d = (getBezierPoint(t + FLT_MIN) //both calls return the same value
             - getBezierPoint(t)) / FLT_MIN; 

    return -(d.x / d.y); // returns the negative inverse of the derivative
}

知道是什么原因造成的吗?

我尝试将 FLT_MIN 替换为 0.000001f,这在大概范围内,但为什么 FLT_MIN 仍然是 0?

c++ graphics floating-point limit calculus
1个回答
0
投票

即使计算参数

t + FLT_MIN
,也会得到相同的结果。此加法的结果将是
t
。这就是浮点数的工作原理。
FLT_MIN
是计算结果可以获得的最小值,但这并不意味着如果将其添加到
0
,那么您将得到
0
以外的数字。浮点数允许您使用非常小的值和非常大的值,但不能同时使用小值和大值。增量步长取决于值的指数。

这是一个简单的示例(不考虑尾数溢出):

float t = 1;
auto i = *(uint32_t*)&t;
i++;    // mantissa increment
float next_t = *(float*)&i;
std::cout << next_t << " - " << t << " = " << next_t - t;

输出:

1 - 1 = 1.19209e-07

也就是说,最接近的大于 1 的数字与其相差 1.19209e-07。

© www.soinside.com 2019 - 2024. All rights reserved.