POV-Ray : Newsgroups : povray.advanced-users : Stepped loop values and mod() Server Time
28 Mar 2024 16:00:28 EDT (-0400)
  Stepped loop values and mod() (Message 1 to 4 of 4)  
From: Bald Eagle
Subject: Stepped loop values and mod()
Date: 2 Aug 2018 19:20:00
Message: <web.5b63908a86504b73458c7afe0@news.povray.org>
I ran into one of those things.
Again.

take a look at:

#for (T, 0, 100, 0.1)
 #debug concat (str(T, 3, 16), "\n")
#end

Around the 13th decimal place there starts to be some > N.0 behaviour which
throws off looking for the regular integer occurrences with mod (N, 1)

I'm curious why it's not in actual even steps of N.10000000000000000000.... out
to however many places POV-Ray numbers go.


Post a reply to this message

From: clipka
Subject: Re: Stepped loop values and mod()
Date: 3 Aug 2018 03:30:51
Message: <5b6404ab$1@news.povray.org>
Am 03.08.2018 um 01:15 schrieb Bald Eagle:
> I ran into one of those things.
> Again.
> 
> take a look at:
> 
> #for (T, 0, 100, 0.1)
>  #debug concat (str(T, 3, 16), "\n")
> #end
> 
> Around the 13th decimal place there starts to be some > N.0 behaviour which
> throws off looking for the regular integer occurrences with mod (N, 1)
> 
> I'm curious why it's not in actual even steps of N.10000000000000000000.... out
> to however many places POV-Ray numbers go.

This is a fundamental problem in floating-point arithmetic - both in
computers and on paper.

As an example, take the rational number 1/3 represented as a decimal
number with, say, 5 significant digits. If you compute 3*(1/3) by adding
1/3 to itself three times, you get:

      0.33333
    + 0.33333
    + 0.33333
    ---------
    = 0.99999

As you can see, the result doesn't quite add up to 1.00000.


The problem always arises when you try to represent a rational number
R=N/M as a finite-digits floating-point number in base B, and the
denominator M of the fraction has at least one prime factor that isn't
also a prime factor of the base B.

In the binary system typically used in computers, this imples that the
problem arises whenever M is not a power of 2.


Note that 0.1 represents a /decimal fraction/, namely 1/10. Since 10 has
5 as one of its prime factors, which isn't a power of 2, the problem
applies here.


In for loops, the problem can be avoided altogether by always using an
integer loop variable, and from that "technical" loop variable compute
an "effective" loop variable via multiplication or division, e.g.:

    #for (I, 0, 1000, 1)
        #local T = I * 0.1;
        ....
    #end


Post a reply to this message

From: Bald Eagle
Subject: Re: Stepped loop values and mod()
Date: 3 Aug 2018 08:35:01
Message: <web.5b644b9e3fc5936fc437ac910@news.povray.org>
clipka <ano### [at] anonymousorg> wrote:


> In the binary system typically used in computers, this imples that the
> problem arises whenever M is not a power of 2.

So, POV-Ray reinforces the patriarchal stranglehold that the Old Boy's Club  has
on implementing a non-binary system, eh?

> Note that 0.1 represents a /decimal fraction/, namely 1/10. Since 10 has
> 5 as one of its prime factors, which isn't a power of 2, the problem
> applies here.


I thought it was something like that - just wanted to be sure.


> In for loops, the problem can be avoided altogether by always using an
> integer loop variable, and from that "technical" loop variable compute
> an "effective" loop variable via multiplication or division, e.g.:
>
>     #for (I, 0, 1000, 1)
>         #local T = I * 0.1;
>         ....
>     #end

Well, this is interesting:
(a) it works - thanks!  :)

(b) my #debug output still shows a "remainder" in the 14th or 15th decimal place
- is that just an artifact showing up _after_ mod() is made happy?


Post a reply to this message

From: Alain
Subject: Re: Stepped loop values and mod()
Date: 3 Aug 2018 10:54:11
Message: <5b646c93$1@news.povray.org>
Le 18-08-03 à 08:33, Bald Eagle a écrit :
> clipka <ano### [at] anonymousorg> wrote:
> 
> 
>> In the binary system typically used in computers, this imples that the
>> problem arises whenever M is not a power of 2.
> 
> So, POV-Ray reinforces the patriarchal stranglehold that the Old Boy's Club  has
> on implementing a non-binary system, eh?
> 
>> Note that 0.1 represents a /decimal fraction/, namely 1/10. Since 10 has
>> 5 as one of its prime factors, which isn't a power of 2, the problem
>> applies here.
> 
> 
> I thought it was something like that - just wanted to be sure.
> 
> 
>> In for loops, the problem can be avoided altogether by always using an
>> integer loop variable, and from that "technical" loop variable compute
>> an "effective" loop variable via multiplication or division, e.g.:
>>
>>      #for (I, 0, 1000, 1)
>>          #local T = I * 0.1;
>>          ....
>>      #end
> 
> Well, this is interesting:
> (a) it works - thanks!  :)
> 
> (b) my #debug output still shows a "remainder" in the 14th or 15th decimal place
> - is that just an artifact showing up _after_ mod() is made happy?
> 
> 
> 
An error at the 14+th decimal place can be expected due to the limits of 
the FP processor. It only have a finite mantissa length.
You'd need a triple or quadruple precision capable floating point unit.


Post a reply to this message

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