浮点数IM precision在迭代 [英] floating point number imprecision while iterating

查看:110
本文介绍了浮点数IM precision在迭代的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个计算的三维点功能,间距根据范围内的值 [0,1] 。的我面临的问题是,一个二进制浮点数无法重新present正好1。

这是在函数计算数学前pression能够计算一个值 T = 1.0 ,但该值将永远不会被函数接受因为它检查是否在计算范围之前。

  curves_error curves_bezier(curves_PointList *名单,curves_Point * DEST,curves_float T){
    / * ... * /
    如果(T< 0 || T> 1)
        返回curves_invalid_args;
    / * ... * /
    返回curves_no_error;
}

我怎样才能利用此功能,在计算 T = 1.0 三维点?我听说过一些,一个省略号,我认为有一个这样的问题做的,但我不知道前一段时间。

感谢

修改:好吧,我很抱歉。我以为一个浮动不能重新present正好是1,因为这个问题,我面对的问题。该问题可能是因为我是做一个迭代是这样的:

 对于(t = 0; T< = 1.0; T + = 0.1){
    curves_error错误= curves_bezier(点,点,T);
    如果(错误!= curves_no_error)
        的printf(错误与T =%F \\ n,T);
    其他
        的printf(T =%f是OK \\ n,T);
}


解决方案

 对于(t = 0; T< = 1.0; T + = 0.1){

你的问题是,一个二进制浮点数字可以不完全重新present 0.1

最接近的32位单precision IEEE754浮点数0.100000001490116119384765625和最接近的64位双precision 1 0.1000000000000000055511151231257827021181583404541015625。如果是在32位precision严格执行算术,加入 0.1F 十次为0的结果是

  1.00000011920928955078125

如果中间计算比更大precision进行浮动有,也可能导致正好 1.0 甚至略有更小的数字。

要解决您的问题,在这种情况下,你可以使用

 的(K = 0; K< = 10; ++ K){
    T = K * 0.1;

由于 10 * 0.1F 完全 1.0

另一种选择是使用你的 curves_bezier 功能的小忍,

 如果(T> 1安培;& T公司< 1 +小量){
    T = 1;
}

对于适当小的ε,也许浮动EPSILON = 1E-6。

I have a function that computes a point in 3d spaced based on a value in range [0, 1]. The problem I'm facing is, that a binary floating-point number cannot represent exactly 1.

The mathematical expression that is evaluated in the function is able to compute a value for t=1.0, but the value will never be accepted by the function because it checks if for the range before computing.

curves_error curves_bezier(curves_PointList* list, curves_Point* dest, curves_float t) {
    /* ... */
    if (t < 0 || t > 1)
        return curves_invalid_args;
    /* ... */
    return curves_no_error;
}

How can I, with this function, compute the 3d point at t=1.0? I heard something about an ELLIPSIS some time ago that I think had to do with such an issue, but I'm not sure.

Thanks

EDIT: Ok, I'm sorry. I assumed a float cannot represent exactly 1, because of the issue I'm facing. The problem may be because I was doing an iteration like this:

for (t=0; t <= 1.0; t += 0.1) {
    curves_error error = curves_bezier(points, point, t);
    if (error != curves_no_error)
        printf("Error with t = %f.\n", t);
    else
        printf("t = %f is ok.\n", t);
}

解决方案

for (t=0; t <= 1.0; t += 0.1) {

your problem is that a binary floating point number cannot exactly represent 0.1.

The closest 32-bit single precision IEEE754 floating point number is 0.100000001490116119384765625 and the closest 64-bit double precision one 0.1000000000000000055511151231257827021181583404541015625. If the arithmetic is performed strictly at 32-bit precision, the result of adding 0.1f ten times to 0 is

1.00000011920928955078125

If intermediate computations are performed at greater precision than float has, it could result in exactly 1.0 or even slightly smaller numbers.

To fix your problem, in this case you could use

for(k = 0; k <= 10; ++k) {
    t = k*0.1;

because 10 * 0.1f is exactly 1.0.

Another option is to use a small tolerance in your curves_bezier function,

if (t > 1 && t < 1 + epsilon) {
    t = 1;
}

for a suitably small epsilon, maybe float epsilon = 1e-6;.

这篇关于浮点数IM precision在迭代的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆