POV-Ray : Newsgroups : povray.bugreports : (X <= D) is not equal ((X<D) | (X=D)) Server Time
13 May 2024 16:38:18 EDT (-0400)
  (X <= D) is not equal ((X<D) | (X=D)) (Message 1 to 1 of 1)  
From: Thorsten Froehlich
Subject: (X <= D) is not equal ((X<D) | (X=D))
Date: 22 Apr 2000 19:47:18
Message: <39023a06@news.povray.org>
From: "Jarek Cora" <jco### [at] pocztafm>
Newsgroups: povray.newusers
Subject: (X <= D) different than  ((X<D) | (X=D)) ?
Date: Sam, 22. Apr 2000 5:11 Uhr

Could someone please explain the following behaviour of POV-Ray 3.1g:
Let's consider a simple while loop:

#local D = 2;
#local X = -D;
#while ((X < D) | (X = D))
   #local X = X + 0.1;
#end
#debug concat("X = ",str(X,0,-1),"\n")

It produces the result X=2.10000, just as I expected.
However when I change the "while" condition to:

#while (X <= D)

the result is: X = 2.000

Why is that? I would expect that (X <= D) and ((X<D) | (X=D)) are
equivalent.

------------------------------------------------

From: Margus Ramst <mar### [at] peakeduee>
Newsgroups: povray.newusers
Subject: Re: (X <= D) different than  ((X<D) | (X=D)) ?
Date: Sam, 22. Apr 2000 8:34 Uhr

Yes, those conditions should be equivalent.
It seems to be a precision-related issue, since the correct result is
achieved by adding some very small value to D in the condition (X <= D).
Also, when the loop is shorter, e.g. D=1, the result is correct for X = X +
0.1 The second version works because for some reason the condition (X = D)
evaluates correctly. However, the conditions like (X != D) (X <= D) etc do
not. I tested this under official 3.1g (Windows & Linux) and Megapov 0.4g
(Windows) and due to the inconsistency regarding conditional operators, it
looks like a bug to me. Comments?

------------------------------------------------

CAUSE AND FIX OF THE PROBLEM:

Technically it is not a bug but a limit in floating-point precision which is
not properly documented.  The reason why the first one works is rather
simple:  POV-Ray already contains a workaround for "is equal" comparisons as
well as "is not equal" ones, but not for smaller/greater (or equal) than
ones.  In reality POV-Ray fixes the problem for the equal and not equal
cases with this method:

condition:   f1 = f2
POV-Ray:     if (fabs(f1 - f2) > EPSILON) then false else true

condition:   f1 != f2
POV-Ray:     if (fabs(f1 - f2) > EPSILON) then true else false

The other comparison operators do not take EPSILON into account.  So
practically POV-Ray should contain a workaround for these cases as well.

Further, the documentation should make clear that floating-point math is
_not_ precise. Especially in long operations the error will build up: There
are some more exact specs for this, but you can safely assume about one
digit per operation. Thus, the example above will accumulate a reasonable
error after its twenty iterations.


      Thorsten


____________________________________________________
Thorsten Froehlich
e-mail: mac### [at] povrayorg

I am a member of the POV-Ray Team.
Visit POV-Ray on the web: http://mac.povray.org


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.