首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么是float.Epsilon而不是zero?

为什么是float.Epsilon而不是zero?
EN

Stack Overflow用户
提问于 2015-05-13 21:37:34
回答 2查看 26.8K关注 0票数 42

在下面的代码中,为什么会有与float.Epsilon的比较,而不是0?

// Coroutine to move elements
protected IEnumerator SmoothMovement (Vector3 end)
{
    // Distance computation
    float sqrRemainingDistance = (transform.position - end).sqrMagnitude;

    while(sqrRemainingDistance > float.Epsilon)
    {
        Vector3 newPostion = Vector3.MoveTowards(
            rb2D.position, end, inverseMoveTime * Time.deltaTime
        );
        rb2D.MovePosition (newPostion);
        sqrRemainingDistance = (transform.position - end).sqrMagnitude;
        yield return null;
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-05-13 22:02:45

实际上,使用float.Epsilon在这里可能不会有任何显著的区别。float.Epsilon是大于零的最小可能的float (大致为1.401298E-45),这并不意味着它是任意两个float之间的最小差。由于浮点数学是不精确的,所以两个看似相等的数字之间的差可能比float.Epsilon大得多。例如:

float f1 = 1.0f / 3.0f;
float f = 1.0f;

(f1 * 3).Dump();  // 1
(f1 * 3 - f).Dump();  // 2.980232E-08

在比较浮点数时,更好的做法是选择一个合理的值来确定两个浮点数是否“足够接近”相等。这是一个上下文定义--例如,对于距离,1 1mm是否“足够近”?也许是在建狗屋的时候,但不是电路板的时候。你不会一直切割一块木头,直到它的长度在目标的1.401298E-45米之内。你要选择一个“足够接近”的差值来表示它们是相等的。

对于sprite运动(我假设这就是在示例中所做的)-也许更合理的"epsilon“是高分辨率监视器上可以表示的最小距离(或者至少是人眼可以注意到的)。

总而言之,sqrRemainingDistance > 0在这里可能也是合理的,因为在0和float.Epsilon之间没有其他数字可以是这个数字,但更好的选择可能是比Epsilon大得多的数字来确定何时停止循环。为了得到一个“合理”的结果,程序可能会进行更多的循环。

事实上,它在MSDN上有文档记录

如果您创建自定义算法来确定是否可以将两个浮点数视为相等,则必须使用大于ε常量的值来建立可接受的绝对差值,才能将这两个值视为相等。(通常,这种差异的幅度比Epsilon大很多倍。)

票数 45
EN

Stack Overflow用户

发布于 2015-05-13 22:07:32

因为floating point math is not precise。我链接的文章很长很详细,所以让我用一个简单的例子来解释:

43.65+61.11=104.75999999999999

背后的原因是浮点数实际上是如何保存的。如果您不想深入研究这个问题,只需记住浮点算术的一般限制,并且不要期望它们完全符合数学原理--包括,在本例中为0。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30216575

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档