POV-Ray : Newsgroups : povray.general : Re: (X <= D) is not equal ((X<D) | (X=D)) Server Time
31 Oct 2024 08:16:16 EDT (-0400)
  Re: (X <= D) is not equal ((X<D) | (X=D)) (Message 1 to 10 of 10)  
From: Peter J  Holzer
Subject: Re: (X <= D) is not equal ((X<D) | (X=D))
Date: 24 Apr 2000 16:01:20
Message: <slrn8g6h9p.e85.hjp-usenet@teal.h.hjp.at>
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] wsracat      |    -- Ale### [at] univieacat
__/   | http://www.hjp.at/ |       zum Thema Portale in at.linux


Post a reply to this message

From: David Fontaine
Subject: Re: (X <= D) is not equal ((X<D) | (X=D))
Date: 24 Apr 2000 17:32:24
Message: <3904BCD8.87C179BA@faricy.net>
"Peter J. Holzer" wrote:

> 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.

Except on TI's where they're in BCD ;)

--
___     _______________________________________________
 | \     |_          <dav### [at] faricynet> <ICQ 55354965>
 |_/avid |ontaine        http://www.faricy.net/~davidf/

"The only difference between me and a madman is that I'm not mad." -Dali


Post a reply to this message

From: Thorsten Froehlich
Subject: Re: (X <= D) is not equal ((X<D) | (X=D))
Date: 24 Apr 2000 20:40:51
Message: <3904e993$1@news.povray.org>
In article <slr### [at] tealhhjpat> , 
hjp### [at] SiKituwsracat (Peter J. Holzer) wrote:

> On Sat, 22 Apr 2000 14:43:54 -0500, Thorsten Froehlich wrote:
>>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.

Be aware that you currently cannot model a solar system in POV-Ray anyway!

I think it does not make sense to have scales the way you suggest, it will
always cause problems with floating-point precision.

> 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.

It is also important to keep it simple for most users.  Telling them that
there are pitfalls when using floating-point math is one thing, forcing them
to know about the exact internals behind floating-point math is inadequate
for a user centric program like POV-Ray.  In my opinion users should be able
to use regular mathematics expressions, and not have to even think about
precision.  Your example above clearly shows how messy and unintuitive it
would be :-)

To solve this problem it might be best to go the way a lot of programs go:
Force maximum (and minimum) limits somewhere in the range of 10e-9 to 10e9.
Thus, if objects are placed outside this limit (the current one is 10e6 I
think) the scene should be rejected.  This would also eliminate the 'new
user wants to model solar system'-error.  The lower bound can not be
enforced, but at least we can tell users that anything below 10e-9 will
fail.  As basically all systems today use IEEE floating-point formats (or
other formats with more, but not less precision) we should be able to define
reasonable small a cross-platform EPSILON that cannot be changed in config.h
(as changing it currently can break scenes).


      Thorsten


PS: Usual disclaimer applies, I do not speak for the team.


Post a reply to this message

From: Peter J  Holzer
Subject: Re: (X <= D) is not equal ((X<D) | (X=D))
Date: 24 Apr 2000 22:05:16
Message: <slrn8g9t77.nf0.hjp-usenet@teal.h.hjp.at>
On Mon, 24 Apr 2000 16:30:00 -0500, David Fontaine wrote:
>"Peter J. Holzer" wrote:
>
>> 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.
>
>Except on TI's where they're in BCD ;)

You have POVray running on a TI? Looks like I have to port it to the
HP48 then (which also uses BCD) :-)

Seriously, apart from pocket calculators I don't know any current
computers which use a decimal representation of fp numbers. I won't
protest if the manual says "On most computers, floating point
numbers are binary", but I would be very surprised if anybody runs
povray on a computer with non-binary floats, even just for amusement
value.

	hp

-- 
   _  | Peter J. Holzer    | Nicht an Tueren mangelt es,
|_|_) | Sysadmin WSR       | sondern an der Einrichtung (aka Content).
| |   | hjp### [at] wsracat      |    -- Ale### [at] univieacat
__/   | http://www.hjp.at/ |       zum Thema Portale in at.linux


Post a reply to this message

From: David Fontaine
Subject: Re: (X <= D) is not equal ((X<D) | (X=D))
Date: 24 Apr 2000 22:08:09
Message: <3904FD81.835E4323@faricy.net>
"Peter J. Holzer" wrote:

> You have POVray running on a TI? Looks like I have to port it to the
> HP48 then (which also uses BCD) :-)

Nah. Too bad, I could be doing something useul during math.

--
___     _______________________________________________
 | \     |_          <dav### [at] faricynet> <ICQ 55354965>
 |_/avid |ontaine        http://www.faricy.net/~davidf/

"The only difference between me and a madman is that I'm not mad." -Dali


Post a reply to this message

From: Warp
Subject: Re: (X <= D) is not equal ((X<D) | (X=D))
Date: 25 Apr 2000 06:55:13
Message: <39057991@news.povray.org>
Peter J. Holzer <hjp### [at] sikituwsracat> wrote:
: 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. 

  Bad idea. You will get lots of accuracy problems that way. Floating
point numbers are inaccurate for extremely huge and small values; there's
nothing we can do about it.

  (So you should not be surprised if you put some object at
<1000000000000000, 0, 0> and another at <1000000000000001, 0, 0> and they
end at the exact same place...)


-- 
main(i,_){for(_?--i,main(i+2,"FhhQHFIJD|FQTITFN]zRFHhhTBFHhhTBFysdB"[i]
):5;i&&_>1;printf("%s",_-70?_&1?"[]":" ":(_=0,"\n")),_/=2);} /*- Warp -*/


Post a reply to this message

From: Peter J  Holzer
Subject: Re: (X <= D) is not equal ((X<D) | (X=D))
Date: 25 Apr 2000 20:02:32
Message: <slrn8gc7l5.rg0.hjp-usenet@teal.h.hjp.at>
On Mon, 24 Apr 2000 19:40:49 -0500, Thorsten Froehlich wrote:
>In article <slr### [at] tealhhjpat> , 
>hjp### [at] SiKituwsracat (Peter J. Holzer) wrote:
>
>> On Sat, 22 Apr 2000 14:43:54 -0500, Thorsten Froehlich wrote:
>>>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.
>
>Be aware that you currently cannot model a solar system in POV-Ray anyway!
>
>I think it does not make sense to have scales the way you suggest, it will
>always cause problems with floating-point precision.

Not if you know what you are doing. Of course you can't expect to have a
scene with the sun at the origin and a space ship and the camera near
pluto. But if the scene is shifted so that the camera is always near the
origin, this should work ok. Floating point arithmetic works just the
same regardless of the scale until you hit the maximum (which is about 
1e308 for IEEE doubles).

>It is also important to keep it simple for most users. Telling them
>that there are pitfalls when using floating-point math is one thing,
>forcing them to know about the exact internals behind floating-point
>math is inadequate for a user centric program like POV-Ray. In my
>opinion users should be able to use regular mathematics expressions,
>and not have to even think about precision. Your example above clearly
>shows how messy and unintuitive it would be :-)

Floating point arithmetic is somewhat messy and unintuitive, but
people have put a lot of thought into defining the rules for IEEE-754
arithmetic to make it predictable.
Adding random workarounds just makes it even more messy and unintuitive
and utterly unpredictable.

>To solve this problem it might be best to go the way a lot of programs
>go: Force maximum (and minimum) limits somewhere in the range of 10e-9
>to 10e9. Thus, if objects are placed outside this limit (the current
>one is 10e6 I think) the scene should be rejected.

Please don't do this. "Nobody needs coordinates larger than 1e9" smells
too much like "nobody needs more than 640kB RAM" or "lines longer than
1000 characters" or "text files larger than 64 kB" for me to make me
comfortable. In 15 years of working with computers I have run way too
often into stupid arbitrary limits.

	hp

-- 
   _  | Peter J. Holzer    | Nicht an Tueren mangelt es,
|_|_) | Sysadmin WSR       | sondern an der Einrichtung (aka Content).
| |   | hjp### [at] wsracat      |    -- Ale### [at] univieacat
__/   | http://www.hjp.at/ |       zum Thema Portale in at.linux


Post a reply to this message

From: Peter J  Holzer
Subject: Re: (X <= D) is not equal ((X<D) | (X=D))
Date: 25 Apr 2000 20:02:38
Message: <slrn8gc7rt.rg0.hjp-usenet@teal.h.hjp.at>
On 25 Apr 2000 06:55:13 -0400, Warp wrote:
>Peter J. Holzer <hjp### [at] sikituwsracat> wrote:
>: 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. 
>
>  Bad idea. You will get lots of accuracy problems that way. Floating
>point numbers are inaccurate for extremely huge and small values; 

This is wrong. FP numbers have exactly the same precision regardless of
the scale (unless you get into the range of denormalized numbers).

>  (So you should not be surprised if you put some object at
><1000000000000000, 0, 0> and another at <1000000000000001, 0, 0> and they
>end at the exact same place...)

Actually, I would be surprised. There are still three binary digits left
:-)

	hp


-- 
   _  | Peter J. Holzer    | Nicht an Tueren mangelt es,
|_|_) | Sysadmin WSR       | sondern an der Einrichtung (aka Content).
| |   | hjp### [at] wsracat      |    -- Ale### [at] univieacat
__/   | http://www.hjp.at/ |       zum Thema Portale in at.linux


Post a reply to this message

From: Warp
Subject: Re: (X <= D) is not equal ((X<D) | (X=D))
Date: 26 Apr 2000 04:56:55
Message: <3906af56@news.povray.org>
Peter J. Holzer <hjp### [at] sikituwsracat> wrote:
: This is wrong. FP numbers have exactly the same precision regardless of
: the scale (unless you get into the range of denormalized numbers).

  Ok, my wording was not mathematically accurate.
  What I was trying to say was that a cylinder of 1 meter at the origin can
be very accurately expressed, but the same cylinder at a distance of
10^100 from the origin will not likely to be exactly 1 meter long because
of accuracy problems.
  This means, for example, that if you are modelling the solar system
with accurate distances and using 1 povray unit as 1 meter, and then you
sloooowly rotate the Earth around the Sun, it will most probably move in
jumps.
  And this of course regardless of your epsilon.

-- 
main(i,_){for(_?--i,main(i+2,"FhhQHFIJD|FQTITFN]zRFHhhTBFHhhTBFysdB"[i]
):5;i&&_>1;printf("%s",_-70?_&1?"[]":" ":(_=0,"\n")),_/=2);} /*- Warp -*/


Post a reply to this message

From: Peter J  Holzer
Subject: Re: (X <= D) is not equal ((X<D) | (X=D))
Date: 26 Apr 2000 20:02:46
Message: <slrn8ges1k.5na.hjp-usenet@teal.h.hjp.at>
On 26 Apr 2000 04:56:55 -0400, Warp wrote:
>  This means, for example, that if you are modelling the solar system
>with accurate distances and using 1 povray unit as 1 meter, and then
>you sloooowly rotate the Earth around the Sun, it will most probably
>move in jumps.

Yes. But the jumps will be almost exactly the same size (in real world
coordinates) whether you use a povray unit of 1 meter or of 1E6 km.
In the first case, the radius of the earth orbit will be about
149.6E9 pov units, and the earth could only move in jumps of 0.00003 pov
units. In the second case the radius would be 149.6 pov units, and the
jump size would be 3e-14 pov units. In both cases that translates to


In fact, because of the non-scaling fuzzy equality operator, you could
distinguish between two adjacent positions in the first case, but not in
the latter.

	hp


-- 
   _  | Peter J. Holzer    | Nicht an Tueren mangelt es,
|_|_) | Sysadmin WSR       | sondern an der Einrichtung (aka Content).
| |   | hjp### [at] wsracat      |    -- Ale### [at] univieacat
__/   | http://www.hjp.at/ |       zum Thema Portale in at.linux


Post a reply to this message

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