Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[for (t=[0:step:1-step]) ...] yields one less than expected #13

Open
charlieb opened this issue Jul 30, 2019 · 6 comments
Open

[for (t=[0:step:1-step]) ...] yields one less than expected #13

charlieb opened this issue Jul 30, 2019 · 6 comments

Comments

@charlieb
Copy link

I'm guessing here but it seems like the intent of the 1-step end condition in the following is that we exclude 1.0 from the array. Thus:

step = 0.01
echo([for (t=[0:step:1-step]) t])

would print [0 ... 0.99] i.e. 100 values but it doesn't. It prints only 99 values: [0 ... 0.98].
This is a little confusing when trying to adapt the code because I end up with a bunch of -2s where I would expect to find only -1s.
This is not exactly a big deal but if someone would confirm the intent is as I expect I will create a pull request with the fixes.

@charlieb
Copy link
Author

Well this is a little odd. I guess this is an openscad bug:

 step = 0.01;
 echo(1.0/step);        

ECHO: 100

 echo([for (t=[0:1.0:1/step]) t]);    

ECHO: [0, ... 100]

 echo([for (t=[0:1.0:0.999999999/step]) t]);                            

ECHO: [0, ... 99]

 echo([for (t=[0:step:1]) t]);

ECHO: [0, ... 0.99]

I'm not sure what to do with that now. I guess it's a floating point issue but my original point still stands, kinda. Please advise.

@MichaelAtOz
Copy link
Member

wiki

You should avoid step values that cannot be represented exactly as binary floating point numbers. Integers are okay, as are fractional values whose denominator is a power of two. For example, 0.25 (1/4) and 0.125 (1/8) are safe, but 0.2 (2/10) should be avoided. The problem with these step values is that your range may have too many or too few elements, due to inexact arithmetic.

@MichaelAtOz
Copy link
Member

I didn't write it but the intent is probably as you say to exclude the last.
Where is that line from, I'm presuming it is in list-comprehension-demo?

@MichaelAtOz
Copy link
Member

for (t=[0:step:1-step/2]) ensures that the final element is >= (1-step) and < 1

@MichaelAtOz
Copy link
Member

This is a good primer to this specific floating point problem.
0.01 as a double is 0.01000000000000000020816681711721685132943093776702880859375

@nophead
Copy link
Member

nophead commented Jul 30, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants