![](/i/fill.gif) |
![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
SharkD <nomail@nomail> wrote:
> There should only be six!
You have found the inaccuracies of floating point numbers.
If you want an exact number of iterations, use integers, and at the
beginning of the loop, calculate the actual value you want to use from
that integer loop counter.
For example, assume you want a loop with a variable which goes from
0 to 1 at steps of 0.1, and stops before it reaches the 1. The correct
way to do that is:
#declare Index = 0;
#while(Index < 10)
#declare Value = Index/10;
... (the body of the loop here, which uses 'Value') ...
#declare Index = Index+1;
#end
This would be the *wrong* way of doing it:
#declare Value = 0;
#while(Value < 1)
...
#declare Value = Value + 0.1;
#end
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
SharkD wrote:
> "SharkD" <nomail@nomail> wrote:
>> Check out this test scene:
>>
>> #local i = 0;
>> #local numerator = 1;
>> #local divisor = 6;
>> #while(i < numerator)
>> #local i = i + numerator/divisor;
>> #debug concat("i = ", str(i, 0, -1),"\n")
>> #end
>>
>> Shouldn't the iterations stop when i = 1? What am I doing wrong?
>
> Just to be clear, the last entry printed to the Messages panel is "i =
> 1.166667".
Change it to this:
#local i = 0;
#local numerator = 1;
#local divisor = 6;
#while(i < numerator)
#debug concat("i = ", str(i, 0, -1),"\n")
#local i = i + numerator/divisor;
#end
and it will end before reporting i>=0.
Regards,
John
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp <war### [at] tag povray org> wrote:
> SharkD <nomail@nomail> wrote:
> > There should only be six!
>
> You have found the inaccuracies of floating point numbers.
>
> If you want an exact number of iterations, use integers, and at the
> beginning of the loop, calculate the actual value you want to use from
> that integer loop counter.
>
> For example, assume you want a loop with a variable which goes from
> 0 to 1 at steps of 0.1, and stops before it reaches the 1. The correct
> way to do that is:
>
> #declare Index = 0;
> #while(Index < 10)
> #declare Value = Index/10;
>
> ... (the body of the loop here, which uses 'Value') ...
>
> #declare Index = Index+1;
> #end
>
> This would be the *wrong* way of doing it:
>
> #declare Value = 0;
> #while(Value < 1)
> ...
> #declare Value = Value + 0.1;
> #end
>
> --
> - Warp
I'm wondering if simply changing the condition to "i < 0.999999" is sufficient.
The likelihood of the variable falling outside this range is pretty slim. Also,
to how many decimal places does POV-Ray calculate? I thought the "system
specific" option in the "str" function returned values using this amount.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
> I'm wondering if simply changing the condition to "i < 0.999999" is sufficient.
> The likelihood of the variable falling outside this range is pretty slim. Also,
> to how many decimal places does POV-Ray calculate? I thought the "system
> specific" option in the "str" function returned values using this amount.
"To how many decimal places does POV-Ray calculate" is the wrong
question to ask. POV-Ray asks your CPU to do floating-point
calculations, that's all. POV-Ray doesn't do numerical calculations in
any different way than the rest of your computer.
Also, floating-point numbers don't even work in terms of "decimal places".
Use this:
#local i = 0;
#local numerator = 1;
#local divisor = 6;
#while(i < divisor)
#local x = i*numerator/divisor;
#debug concat("x = ", str(x, 0, -1),"\n")
#local i = i + 1;
#end
and be done with it.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp <war### [at] tag povray org> wrote:
> SharkD <nomail@nomail> wrote:
> > There should only be six!
>
> You have found the inaccuracies of floating point numbers.
>
> If you want an exact number of iterations, use integers, and at the
> beginning of the loop, calculate the actual value you want to use from
> that integer loop counter.
>
> For example, assume you want a loop with a variable which goes from
> 0 to 1 at steps of 0.1, and stops before it reaches the 1. The correct
> way to do that is:
>
> #declare Index = 0;
> #while(Index < 10)
> #declare Value = Index/10;
>
> ... (the body of the loop here, which uses 'Value') ...
>
> #declare Index = Index+1;
> #end
>
> This would be the *wrong* way of doing it:
>
> #declare Value = 0;
> #while(Value < 1)
> ...
> #declare Value = Value + 0.1;
> #end
>
> --
> - Warp
I changed my code to the following, but still receive the same erros.
#local radii = 6;
#local increment = 1/radii;
#local i = 0;
#local max = radii * increment;
#while(i < max)
#local i = i + increment;
#debug concat("i = ", str(i, 0, -1),"\n")
#end
If "increment" is indeed stored as a float, shouldn't "6 * increment" evaluate
to the same number as "increment + increment + increment + increment +
increment + increment"?
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
"SharkD" <nomail@nomail> wrote:
> I changed my code to the following, but still receive the same erros.
>
> #local radii = 6;
> #local increment = 1/radii;
> #local i = 0;
> #local max = radii * increment;
> #while(i < max)
> #local i = i + increment;
> #debug concat("i = ", str(i, 0, -1),"\n")
> #end
>
> If "increment" is indeed stored as a float, shouldn't "6 * increment" evaluate
> to the same number as "increment + increment + increment + increment +
> increment + increment"?
Nevermind.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
> I'm wondering if simply changing the condition to "i < 0.999999" is
> sufficient.
> The likelihood of the variable falling outside this range is pretty slim.
> Also,
> to how many decimal places does POV-Ray calculate? I thought the "system
> specific" option in the "str" function returned values using this amount.
1/6 is a repeating decimal and binary
0.1(6) decimal, 0.00(10) binary.
In FP this is represented by a significand and an exponent
that moves the decimal place, in binary. The significand for 1/6 is
then stored as 1.(01) in binary, except that repeating decimals
are not dealt with in IEEE 754! They just store 23 bits worth and stop,
so while the actual number should be 1.(01) binary, it's really
using 1.01010101010101010101010 in IEEE 754.
In other words it depends on the size of your increment...
1 in decimal is
1 in binary and
1.00000000000000000000000 in IEEE 754,
so there is no FP error.
0.1 in decimal is
0.000(1100) in binary and
1.10011001100110011001100 in IEEE 754
so it has some FP error.
Decimal numbers that convert to terminating binary
numbers have denominators that are powers of 2.
So for example 3/8 is
0.375 in decimal,
0.011 in binary, and
1.10000000000000000000000 in IEEE 754
so there is no FP error issues with these
numbers either.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
SharkD <nomail@nomail> wrote:
> I thought the "system
> specific" option in the "str" function returned values using this amount.
Nope. It returns the amount of decimals shown by default by printf in clib
(when the number of decimals to show is not specified), which has nothing to
do about how many decimals 64-bit IEEE floating point numbers use.
If you want to know how 64-bit IEEE floating point numbers work, see
http://en.wikipedia.org/wiki/IEEE_754
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
SharkD <nomail@nomail> wrote:
> #local increment = 1/radii;
That's not an integer.
> #local i = i + increment;
And thus your loop counter isn't either.
> If "increment" is indeed stored as a float, shouldn't "6 * increment" evaluate
> to the same number as "increment + increment + increment + increment +
> increment + increment"?
No. We are talking about floating point numbers with limited number of bits.
That kind of thing is *not* guaranteed at all.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
news:web.4785b89a636bc06df6ab856c0@news.povray.org...
> Check out this test scene:
>
> #local i = 0;
> #local numerator = 1;
> #local divisor = 6;
> #while(i < numerator)
> #local i = i + numerator/divisor;
> #debug concat("i = ", str(i, 0, -1),"\n")
> #end
>
> Shouldn't the iterations stop when i = 1? What am I doing wrong?
>
>
here #local i = i + numerator/divisor;
use ; insteed of ,
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |