POV-Ray : Newsgroups : povray.advanced-users : Stepped loop values and mod() : Re: Stepped loop values and mod() Server Time19 Jun 2024 15:48:37 EDT (-0400)
 Re: Stepped loop values and mod()
 From: clipka Date: 3 Aug 2018 03:30:51 Message: <5b6404ab\$1@news.povray.org>
```
{
"@context": "https://schema.org",
"@type": "DiscussionForumPosting",
"@id": "#5b6404ab%241%40news.povray.org",
"headline": "Re: Stepped loop values and mod()",
"dateCreated": "2018-08-03T07:30:51+00:00",
"datePublished": "2018-08-03T07:30:51+00:00",
"author": {
"@type": "Person",
"name": "clipka"
}
}
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
```