|
![](/i/fill.gif) |
On Sat, 22 Apr 2000 14:43:54 -0500, Thorsten Froehlich wrote:
>
>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.
I disagree. This workaround assumes that all numbers are in a certain
range (about 1E-3 ... 1E6). While this may be true for most scenes it
certainly isn't universally true. In my scene files one pov unit is
always one meter, whether I am modelling the circuits of a microchip or
the whole solar system.
From reading IRTC entry descriptions I get the impression that I am not
the only one who puts the sun at the correct distance even for "everyday
scenes". I have occasionally encountered weird behaviour at large
scales, which I now suspect to be caused by this workaround (I will
check this and then post a followup).
A better expression for a "fuzzy" equality operator would be:
f1 == f2 ? 1 : fabs(f1 - f2) / max(fabs(f1), fabs(f2)) < EPSILON
but I don't think it should be fuzzy at all.
>Further, the documentation should make clear that floating-point math is
>_not_ precise.
Right. Especially make it clear that floating point numbers are binary
and cannot exactly represent fractions which are not a multiple of some
power of two. 1/2, 3/4, 356/1024 can be exactly represented, but 1/10
cannot (just like 1/3 cannot be exactly represented in decimal).
Therefore 10 * 0.1 is not equal to 1.
Instead of
#local D = 2;
#local X = -D;
#while (X <= D)
#local X = X + 0.1;
do_something_with(X)
#end
write
#local D = 20;
#local X1 = -D;
#while (X1 <= D)
#local X1 = X1 + 1;
#local X = X/10
do_something_with(X)
#end
this is exact and will produce the expected result.
hp
PS: I see that EPSILON is used quite often in the sources. I have not
checked if it is used correctly in other places.
--
_ | Peter J. Holzer | Nicht an Tueren mangelt es,
|_|_) | Sysadmin WSR | sondern an der Einrichtung (aka Content).
| | | hjp### [at] wsr ac at | -- Ale### [at] univie ac at
__/ | http://www.hjp.at/ | zum Thema Portale in at.linux
Post a reply to this message
|
![](/i/fill.gif) |