Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
195 views
in Technique[技术] by (71.8m points)

c# - Why float.Epsilon and not zero?

In the following code, why is there a comparison against float.Epsilon and not 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;
    }
}
question from:https://stackoverflow.com/questions/30216575/why-float-epsilon-and-not-zero

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Actually, using float.Epsilon may not make any significant difference here. float.Epsilon is the smallest possible float greater than zero (roughly 1.401298E-45), which does not mean that it's the smallest difference between any two arbitrary floats. Since floating-point math is imprecise, the difference between two seemingly equal numbers can be much greater than float.Epsilon. For example:

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

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

When comparing floats, a better practice is to choose a reasonable value to determine if two floats are "close enough" to be equal. That's a contextual definition - e.g. for distance, is 1mm "close enough"? Maybe when building a doghouse, but not a circuit board. You're not going to keep cutting a piece of wood until it's length is within 1.401298E-45 meters of the target. You're going to choose a difference that's "close enough" to call them equal.

For sprite movement (which I'm assuming that's what's being done in the sample) - maybe a more reasonable "epsilon" is the smallest distance that can be represented on a high-res monitor (or at least that would be noticed by the human eye).

All that to say that sqrRemainingDistance > 0 may be just as reasonable here, since there's no other number between 0 and float.Epsilon that the number could be, but a better choice may be some number much larger than Epsilon to determine when to stop looping. The program may be looping a lot more than it has to in order to get to a "reasonable" result.

In fact, it's documented on MSDN:

If you create a custom algorithm that determines whether two floating-point numbers can be considered equal, you must use a value that is greater than the Epsilon constant to establish the acceptable absolute margin of difference for the two values to be considered equal. (Typically, that margin of difference is many times greater than Epsilon.)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...