discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Apparently I don't understand modulo

GH
gene heskett
Fri, Nov 10, 2023 2:34 PM

Greetings all;

Attempting to get a true/false in an if statement, I used the ( i % .2)
construct to cause a 180 degree rotation in order to fit more on the
printers plate. But its not working as expected. is the % supposed to
yield a remainder of a division?

This code works for i=.3 to .5 step .1
but fails for i=.3 to .6 or higher
module test_nuts() // will print the first 3 on the e5-s1
{  yofs=15;
for(i=[.30:.10:.50])
{
echo(184,i,(i % .20));
tsz=str(i);
echo(186,tsz);
yloc=(i-.3)*450;
if(i %
.20)translate([20,yofs+yloc-60,0])short_test_newnut(nozzle,3,tsz);
else
translate([195,yofs+yloc+140,0])rotate([0,0,180])short_test_newnut(nozzle,3,tsz);
}
}
test_nuts();

word wrap in tbird can't be turned off, the if/else are really just 2 lines.
from the log window:
ECHO: 184, 0.3, 0.1
ECHO: 184, 0.4, 0
ECHO: 184, 0.5, 0.1
but if I goto .60, it gets this
ECHO: 184, 0.6, 5.55112e-17 and from there on, where it s/b 0, its not.

Help, if there is any.
this is linux AppImage 2023.09.10.ai16125 (git dcaf25f0e)

Cheers, Gene Heskett.

"There are four boxes to be used in defense of liberty:
soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author, 1940)
If we desire respect for the law, we must first make the law respectable.

  • Louis D. Brandeis
Greetings all; Attempting to get a true/false in an if statement, I used the ( i % .2) construct to cause a 180 degree rotation in order to fit more on the printers plate. But its not working as expected. is the % supposed to yield a remainder of a division? This code works for i=.3 to .5 step .1 but fails for i=.3 to .6 or higher module test_nuts() // will print the first 3 on the e5-s1 { yofs=15; for(i=[.30:.10:.50]) { echo(184,i,(i % .20)); tsz=str(i); echo(186,tsz); yloc=(i-.3)*450; if(i % .20)translate([20,yofs+yloc-60,0])short_test_newnut(nozzle,3,tsz); else translate([195,yofs+yloc+140,0])rotate([0,0,180])short_test_newnut(nozzle,3,tsz); } } test_nuts(); word wrap in tbird can't be turned off, the if/else are really just 2 lines. from the log window: ECHO: 184, 0.3, 0.1 ECHO: 184, 0.4, 0 ECHO: 184, 0.5, 0.1 but if I goto .60, it gets this ECHO: 184, 0.6, 5.55112e-17 and from there on, where it s/b 0, its not. Help, if there is any. this is linux AppImage 2023.09.10.ai16125 (git dcaf25f0e) Cheers, Gene Heskett. -- "There are four boxes to be used in defense of liberty: soap, ballot, jury, and ammo. Please use in that order." -Ed Howdershelt (Author, 1940) If we desire respect for the law, we must first make the law respectable. - Louis D. Brandeis
CK
Chun Kit LAM
Fri, Nov 10, 2023 2:39 PM

You are correct, but floating point causes inaccuracy so 0.6%0.2 is not
exactly 0. You can either accept the error and do something like abs(x %
0.2) > c where c is a small constant, or used fixed-precision arithmetic
(basically multiply everything with a factor to make them integers).

On 10/11/2023 22:34, gene heskett via Discuss wrote:

Greetings all;

Attempting to get a true/false in an if statement, I used the ( i %
.2) construct to cause a 180 degree rotation in order to fit more on
the printers plate. But its not working as expected. is the % supposed
to yield a remainder of a division?

This code works for i=.3 to .5 step .1
but fails for i=.3 to .6 or higher
module test_nuts() // will print the first 3 on the e5-s1
{   yofs=15;
    for(i=[.30:.10:.50])
    {
        echo(184,i,(i % .20));
        tsz=str(i);
        echo(186,tsz);
        yloc=(i-.3)*450;
        if(i %
.20)translate([20,yofs+yloc-60,0])short_test_newnut(nozzle,3,tsz);
        else
translate([195,yofs+yloc+140,0])rotate([0,0,180])short_test_newnut(nozzle,3,tsz);
    }
}
test_nuts();

word wrap in tbird can't be turned off, the if/else are really just 2
lines.
from the log window:
ECHO: 184, 0.3, 0.1
ECHO: 184, 0.4, 0
ECHO: 184, 0.5, 0.1
but if I goto .60, it gets this
ECHO: 184, 0.6, 5.55112e-17 and from there on, where it s/b 0, its not.

Help, if there is any.
this is linux AppImage 2023.09.10.ai16125 (git dcaf25f0e)

Cheers, Gene Heskett.


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

You are correct, but floating point causes inaccuracy so 0.6%0.2 is not exactly 0. You can either accept the error and do something like abs(x % 0.2) > c where c is a small constant, or used fixed-precision arithmetic (basically multiply everything with a factor to make them integers). On 10/11/2023 22:34, gene heskett via Discuss wrote: > Greetings all; > > Attempting to get a true/false in an if statement, I used the ( i % > .2) construct to cause a 180 degree rotation in order to fit more on > the printers plate. But its not working as expected. is the % supposed > to yield a remainder of a division? > > This code works for i=.3 to .5 step .1 > but fails for i=.3 to .6 or higher > module test_nuts() // will print the first 3 on the e5-s1 > {   yofs=15; >     for(i=[.30:.10:.50]) >     { >         echo(184,i,(i % .20)); >         tsz=str(i); >         echo(186,tsz); >         yloc=(i-.3)*450; >         if(i % > .20)translate([20,yofs+yloc-60,0])short_test_newnut(nozzle,3,tsz); >         else > translate([195,yofs+yloc+140,0])rotate([0,0,180])short_test_newnut(nozzle,3,tsz); >     } > } > test_nuts(); > > word wrap in tbird can't be turned off, the if/else are really just 2 > lines. > from the log window: > ECHO: 184, 0.3, 0.1 > ECHO: 184, 0.4, 0 > ECHO: 184, 0.5, 0.1 > but if I goto .60, it gets this > ECHO: 184, 0.6, 5.55112e-17 and from there on, where it s/b 0, its not. > > Help, if there is any. > this is linux AppImage 2023.09.10.ai16125 (git dcaf25f0e) > > Cheers, Gene Heskett. > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org
PC
Patrick Callahan
Fri, Nov 10, 2023 3:17 PM

The mathematics behind the % operation applies only to the set of
integers.  When applied to floating point numbers, things get weird.  And
small.
The decimal arithmetic remainder at the precision you specified in the data
would be what you expect, but the representation of the numbers as binary
fractions is more frequently rounded as many numbers we would expect to be
perfectly representable in 64 bits when converted to base 2 are an infinite
number of digits long.

0.1 is a famous example:
0.0001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011
I could keep going, but you get the idea.  Definitely not representable in
64 bits.

Most fractions represented as decimals (0.1, 0.2, 0.3, 0.11, 3.14159 etc.)
are not exactly representable in 64 bits.  Floating point numbers should
be treated as approximations always.

After you perform a floating point operation on any number and convert it
back to decimal, you may or may not see the same number you expect.

It's that "feature" of floating point operations that causes small deltas
in any number produced by the FDM during stable flight.

https://stackoverflow.com/questions/6102948/why-does-modulus-division-only-work-with-integers

On Fri, Nov 10, 2023 at 9:34 AM gene heskett via Discuss <
discuss@lists.openscad.org> wrote:

Greetings all;

Attempting to get a true/false in an if statement, I used the ( i % .2)
construct to cause a 180 degree rotation in order to fit more on the
printers plate. But its not working as expected. is the % supposed to
yield a remainder of a division?

This code works for i=.3 to .5 step .1
but fails for i=.3 to .6 or higher
module test_nuts() // will print the first 3 on the e5-s1
{  yofs=15;
for(i=[.30:.10:.50])
{
echo(184,i,(i % .20));
tsz=str(i);
echo(186,tsz);
yloc=(i-.3)*450;
if(i %
.20)translate([20,yofs+yloc-60,0])short_test_newnut(nozzle,3,tsz);
else

translate([195,yofs+yloc+140,0])rotate([0,0,180])short_test_newnut(nozzle,3,tsz);
}
}
test_nuts();

word wrap in tbird can't be turned off, the if/else are really just 2
lines.
from the log window:
ECHO: 184, 0.3, 0.1
ECHO: 184, 0.4, 0
ECHO: 184, 0.5, 0.1
but if I goto .60, it gets this
ECHO: 184, 0.6, 5.55112e-17 and from there on, where it s/b 0, its not.

Help, if there is any.
this is linux AppImage 2023.09.10.ai16125 (git dcaf25f0e)

Cheers, Gene Heskett.

"There are four boxes to be used in defense of liberty:
soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author, 1940)
If we desire respect for the law, we must first make the law respectable.

The mathematics behind the % operation applies only to the set of integers. When applied to floating point numbers, things get weird. And small. The decimal arithmetic remainder at the precision you specified in the data would be what you expect, but the representation of the numbers as binary fractions is more frequently rounded as many numbers we would expect to be perfectly representable in 64 bits when converted to base 2 are an infinite number of digits long. 0.1 is a famous example: 0.0001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011 I could keep going, but you get the idea. Definitely not representable in 64 bits. Most fractions represented as decimals (0.1, 0.2, 0.3, 0.11, 3.14159 etc.) are not exactly representable in 64 bits. Floating point numbers should be treated as approximations always. After you perform a floating point operation on any number and convert it back to decimal, you may or may not see the same number you expect. It's that "feature" of floating point operations that causes small deltas in any number produced by the FDM during stable flight. https://stackoverflow.com/questions/6102948/why-does-modulus-division-only-work-with-integers On Fri, Nov 10, 2023 at 9:34 AM gene heskett via Discuss < discuss@lists.openscad.org> wrote: > Greetings all; > > Attempting to get a true/false in an if statement, I used the ( i % .2) > construct to cause a 180 degree rotation in order to fit more on the > printers plate. But its not working as expected. is the % supposed to > yield a remainder of a division? > > This code works for i=.3 to .5 step .1 > but fails for i=.3 to .6 or higher > module test_nuts() // will print the first 3 on the e5-s1 > { yofs=15; > for(i=[.30:.10:.50]) > { > echo(184,i,(i % .20)); > tsz=str(i); > echo(186,tsz); > yloc=(i-.3)*450; > if(i % > .20)translate([20,yofs+yloc-60,0])short_test_newnut(nozzle,3,tsz); > else > > translate([195,yofs+yloc+140,0])rotate([0,0,180])short_test_newnut(nozzle,3,tsz); > } > } > test_nuts(); > > word wrap in tbird can't be turned off, the if/else are really just 2 > lines. > from the log window: > ECHO: 184, 0.3, 0.1 > ECHO: 184, 0.4, 0 > ECHO: 184, 0.5, 0.1 > but if I goto .60, it gets this > ECHO: 184, 0.6, 5.55112e-17 and from there on, where it s/b 0, its not. > > Help, if there is any. > this is linux AppImage 2023.09.10.ai16125 (git dcaf25f0e) > > Cheers, Gene Heskett. > -- > "There are four boxes to be used in defense of liberty: > soap, ballot, jury, and ammo. Please use in that order." > -Ed Howdershelt (Author, 1940) > If we desire respect for the law, we must first make the law respectable. > - Louis D. Brandeis_______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
JB
Jordan Brown
Fri, Nov 10, 2023 5:48 PM

On 11/10/2023 7:17 AM, Patrick Callahan via Discuss wrote:

The mathematics behind the % operation applies only to the set of
integers.  When applied to floating point numbers, things get weird.

I wouldn't say so.  mod(a,b) = a - floor(a/b)*b.  Behaves perfectly
sensibly for non-integers.

But I agree that Gene's problem is that many decimal fractions are
infinite repeating fractions in binary, and so cannot be represented
precisely.

In general, you can't do floating point arithmetic and expect exact
results.  It's very likely that you will get an error somewhere around
one part in 10^16 .

Similarly, in "for (i=[.30:.10:.50])" I wouldn't be surprised if you
didn't see 0.50.  I don't happen to remember how OpenSCAD does ranges,
but if it does them by adding up the increment it might end up with that
last one being 0.50000000001 and so past the end, or if it does it by
subtracting, dividing, flooring, and then counting and multiplying, it
might end up with the division saying there are 2.9999999999 steps and
flooring to 2.  (There would really be more zeroes and nines than that,
but I figured you'd get bored.)  I think it uses the
divide/count/multiply strategy.

I think floating point should use base 210 notation.  It's almost as
efficient as binary, but gets precise results for division by 2, 3, 5,
and 7.

On 11/10/2023 7:17 AM, Patrick Callahan via Discuss wrote: > The mathematics behind the % operation applies only to the set of > integers.  When applied to floating point numbers, things get weird. I wouldn't say so.  mod(a,b) = a - floor(a/b)*b.  Behaves perfectly sensibly for non-integers. But I agree that Gene's problem is that many decimal fractions are infinite repeating fractions in binary, and so cannot be represented precisely. In general, you can't do floating point arithmetic and expect exact results.  It's very likely that you will get an error somewhere around one part in 10^16 . Similarly, in "for (i=[.30:.10:.50])" I wouldn't be surprised if you didn't see 0.50.  I don't happen to remember how OpenSCAD does ranges, but if it does them by adding up the increment it might end up with that last one being 0.50000000001 and so past the end, or if it does it by subtracting, dividing, flooring, and then counting and multiplying, it might end up with the division saying there are 2.9999999999 steps and flooring to 2.  (There would really be more zeroes and nines than that, but I figured you'd get bored.)  I think it uses the divide/count/multiply strategy. I think floating point should use base 210 notation.  It's almost as efficient as binary, but gets precise results for division by 2, 3, 5, and 7.
AM
Adrian Mariano
Fri, Nov 10, 2023 9:18 PM

The take home message here is that it's a mistake to use an equality test
with floating point numbers.  You always need to test something like
abs(x-y)<1e-15 or whatever threshold you like there if you want robust
behavior to check if x and y are equal floating point values.  (Note, the
correct threshold depends on the precision of the calculations that gave
rise to x and y but also the complexity of those calculations.  In a
complex calculation, round-off errors accumulate and so a larger threshold
would be appropriate.)

On Fri, Nov 10, 2023 at 12:49 PM Jordan Brown via Discuss <
discuss@lists.openscad.org> wrote:

On 11/10/2023 7:17 AM, Patrick Callahan via Discuss wrote:

The mathematics behind the % operation applies only to the set of
integers.  When applied to floating point numbers, things get weird.

I wouldn't say so.  mod(a,b) = a - floor(a/b)*b.  Behaves perfectly
sensibly for non-integers.

But I agree that Gene's problem is that many decimal fractions are
infinite repeating fractions in binary, and so cannot be represented
precisely.

In general, you can't do floating point arithmetic and expect exact
results.  It's very likely that you will get an error somewhere around one
part in 1016.

Similarly, in "for (i=[.30:.10:.50])" I wouldn't be surprised if you
didn't see 0.50.  I don't happen to remember how OpenSCAD does ranges, but
if it does them by adding up the increment it might end up with that last
one being 0.50000000001 and so past the end, or if it does it by
subtracting, dividing, flooring, and then counting and multiplying, it
might end up with the division saying there are 2.9999999999 steps and
flooring to 2.  (There would really be more zeroes and nines than that, but
I figured you'd get bored.)  I think it uses the divide/count/multiply
strategy.

I think floating point should use base 210 notation.  It's almost as
efficient as binary, but gets precise results for division by 2, 3, 5, and
7.


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

The take home message here is that it's a mistake to use an equality test with floating point numbers. You always need to test something like abs(x-y)<1e-15 or whatever threshold you like there if you want robust behavior to check if x and y are equal floating point values. (Note, the correct threshold depends on the precision of the calculations that gave rise to x and y but also the complexity of those calculations. In a complex calculation, round-off errors accumulate and so a larger threshold would be appropriate.) On Fri, Nov 10, 2023 at 12:49 PM Jordan Brown via Discuss < discuss@lists.openscad.org> wrote: > On 11/10/2023 7:17 AM, Patrick Callahan via Discuss wrote: > > The mathematics behind the % operation applies only to the set of > integers. When applied to floating point numbers, things get weird. > > > I wouldn't say so. mod(a,b) = a - floor(a/b)*b. Behaves perfectly > sensibly for non-integers. > > But I agree that Gene's problem is that many decimal fractions are > infinite repeating fractions in binary, and so cannot be represented > precisely. > > In general, you can't do floating point arithmetic and expect exact > results. It's very likely that you will get an error somewhere around one > part in 1016. > > Similarly, in "for (i=[.30:.10:.50])" I wouldn't be surprised if you > didn't see 0.50. I don't happen to remember how OpenSCAD does ranges, but > if it does them by adding up the increment it might end up with that last > one being 0.50000000001 and so past the end, or if it does it by > subtracting, dividing, flooring, and then counting and multiplying, it > might end up with the division saying there are 2.9999999999 steps and > flooring to 2. (There would really be more zeroes and nines than that, but > I figured you'd get bored.) I think it uses the divide/count/multiply > strategy. > > I think floating point should use base 210 notation. It's almost as > efficient as binary, but gets precise results for division by 2, 3, 5, and > 7. > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
JB
Jordan Brown
Fri, Nov 10, 2023 10:13 PM

On 11/10/2023 1:18 PM, Adrian Mariano via Discuss wrote:

(Note, the correct threshold depends on the precision of the
calculations that gave rise to x and y but also the complexity of
those calculations.  In a complex calculation, round-off errors
accumulate and so a larger threshold would be appropriate.)

(I know you know this; this addition is for those who need it.)

And on the magnitude of the values.  The error for 64-bit floating point
is around one part in 1e16.  If the numbers you're working with are
around 1, that means that the error will be around 1e-16, but if the
numbers you are working with are around a million, the error will be
around 1e-10.

Floating point arithmetic does have a problem with exact equality, but
often gets a bum rap with claims that it is inaccurate.  If you're
working with 64-bit floating point and you're seeing a macroscopic
effect (other than because of an equality test), it is not due to
floating point inaccuracy.  64-bit floating point is more than accurate
enough to measure the distance from the Earth to the Sun in millimeters,
or the distance from Los Angeles to New York in nanometers.  Even the
less common 32-bit floating point (notable for us because binary STL
uses it) is enough for one part in ten million, so you can measure the
distance from Los Angeles to New York in meters, or your height in
micrometers.  Even with 32-bit floating point, if you're measuring a
physical thing and you can see a macroscopic error, it's not because of
floating point precision.

Note also that decimal arithmetic has the very same issues, just with
different values.  1/3 in decimal is 0.3333333; if you add up three of
those you might well end up with 0.99999999 rather than 1.0.  The fact
that 1/10 is imprecise in binary floating point bothers us because we're
used to representing 1/10 precisely, but we're used to 1/3 not being
represented precisely.


Like I said, base 210.  1/10 is 0.(21), 1/7 is 0.(30), 1/49 is
0.(4)(60).  Spread the word :-)

On 11/10/2023 1:18 PM, Adrian Mariano via Discuss wrote: > (Note, the correct threshold depends on the precision of the > calculations that gave rise to x and y but also the complexity of > those calculations.  In a complex calculation, round-off errors > accumulate and so a larger threshold would be appropriate.) (I know you know this; this addition is for those who need it.) And on the magnitude of the values.  The error for 64-bit floating point is around one part in 1e16.  If the numbers you're working with are around 1, that means that the error will be around 1e-16, but if the numbers you are working with are around a million, the error will be around 1e-10. Floating point arithmetic does have a problem with exact equality, but often gets a bum rap with claims that it is inaccurate.  If you're working with 64-bit floating point and you're seeing a macroscopic effect (other than because of an equality test), it is *not* due to floating point inaccuracy.  64-bit floating point is more than accurate enough to measure the distance from the Earth to the Sun in millimeters, or the distance from Los Angeles to New York in nanometers.  Even the less common 32-bit floating point (notable for us because binary STL uses it) is enough for one part in ten million, so you can measure the distance from Los Angeles to New York in meters, or your height in micrometers.  Even with 32-bit floating point, if you're measuring a physical thing and you can see a macroscopic error, it's not because of floating point precision. Note also that decimal arithmetic has the very same issues, just with different values.  1/3 in decimal is 0.3333333; if you add up three of those you might well end up with 0.99999999 rather than 1.0.  The fact that 1/10 is imprecise in binary floating point bothers us because we're used to representing 1/10 precisely, but we're used to 1/3 not being represented precisely. --- Like I said, base 210.  1/10 is 0.(21), 1/7 is 0.(30), 1/49 is 0.(4)(60).  Spread the word :-)
GH
gene heskett
Sat, Nov 11, 2023 1:18 AM

On 11/10/23 09:39, Chun Kit LAM via Discuss wrote:

You are correct, but floating point causes inaccuracy so 0.6%0.2 is not
exactly 0. You can either accept the error and do something like abs(x %
0.2) > c where c is a small constant, or used fixed-precision arithmetic
(basically multiply everything with a factor to make them integers).

Ok, I've done that and it works up to a final target of .90 but fails
for target values of 1.0 and up.  So what I and going to do is use that
basic code and add an offset to the var i to make the rest of this up to
about 4.0. What I'm making is a gauge set, with the buttress thread
increasing from a starter value to that + the amount printed on the tab.

Screws vary because of sawing errors, bandsaws wander and are reduced in
diameter until the flat side of a 2x2 disappears. The variation can be
as much as a millimeter, maybe more. And it appears I need to size the
OD of the ring just to maintain solidarity to the print when the threads
grow. Is there a function that makes a numerical value from a string
"3.5". This will allow me to make the OD autosize according to the
thread size.  Or I could add i+d to the make nut call. Unexplored
territory for me. I'll probably get it, that's how I learn, by doing.

Thanks for the help, its appreciated.
Take care & stay well.

On 10/11/2023 22:34, gene heskett via Discuss wrote:

Greetings all;

Attempting to get a true/false in an if statement, I used the ( i %
.2) construct to cause a 180 degree rotation in order to fit more on
the printers plate. But its not working as expected. is the % supposed
to yield a remainder of a division?

This code works for i=.3 to .5 step .1
but fails for i=.3 to .6 or higher
module test_nuts() // will print the first 3 on the e5-s1
{   yofs=15;
    for(i=[.30:.10:.50])
    {
        echo(184,i,(i % .20));
        tsz=str(i);
        echo(186,tsz);
        yloc=(i-.3)*450;
        if(i %
.20)translate([20,yofs+yloc-60,0])short_test_newnut(nozzle,3,tsz);
        else
translate([195,yofs+yloc+140,0])rotate([0,0,180])short_test_newnut(nozzle,3,tsz);
    }
}
test_nuts();

word wrap in tbird can't be turned off, the if/else are really just 2
lines.
from the log window:
ECHO: 184, 0.3, 0.1
ECHO: 184, 0.4, 0
ECHO: 184, 0.5, 0.1
but if I goto .60, it gets this
ECHO: 184, 0.6, 5.55112e-17 and from there on, where it s/b 0, its not.

Help, if there is any.
this is linux AppImage 2023.09.10.ai16125 (git dcaf25f0e)

Cheers, Gene Heskett.


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Cheers, Gene Heskett.

"There are four boxes to be used in defense of liberty:
soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author, 1940)
If we desire respect for the law, we must first make the law respectable.

  • Louis D. Brandeis
On 11/10/23 09:39, Chun Kit LAM via Discuss wrote: > You are correct, but floating point causes inaccuracy so 0.6%0.2 is not > exactly 0. You can either accept the error and do something like abs(x % > 0.2) > c where c is a small constant, or used fixed-precision arithmetic > (basically multiply everything with a factor to make them integers). > Ok, I've done that and it works up to a final target of .90 but fails for target values of 1.0 and up. So what I and going to do is use that basic code and add an offset to the var i to make the rest of this up to about 4.0. What I'm making is a gauge set, with the buttress thread increasing from a starter value to that + the amount printed on the tab. Screws vary because of sawing errors, bandsaws wander and are reduced in diameter until the flat side of a 2x2 disappears. The variation can be as much as a millimeter, maybe more. And it appears I need to size the OD of the ring just to maintain solidarity to the print when the threads grow. Is there a function that makes a numerical value from a string "3.5". This will allow me to make the OD autosize according to the thread size. Or I could add i+d to the make nut call. Unexplored territory for me. I'll probably get it, that's how I learn, by doing. Thanks for the help, its appreciated. Take care & stay well. > On 10/11/2023 22:34, gene heskett via Discuss wrote: >> Greetings all; >> >> Attempting to get a true/false in an if statement, I used the ( i % >> .2) construct to cause a 180 degree rotation in order to fit more on >> the printers plate. But its not working as expected. is the % supposed >> to yield a remainder of a division? >> >> This code works for i=.3 to .5 step .1 >> but fails for i=.3 to .6 or higher >> module test_nuts() // will print the first 3 on the e5-s1 >> {   yofs=15; >>     for(i=[.30:.10:.50]) >>     { >>         echo(184,i,(i % .20)); >>         tsz=str(i); >>         echo(186,tsz); >>         yloc=(i-.3)*450; >>         if(i % >> .20)translate([20,yofs+yloc-60,0])short_test_newnut(nozzle,3,tsz); >>         else >> translate([195,yofs+yloc+140,0])rotate([0,0,180])short_test_newnut(nozzle,3,tsz); >>     } >> } >> test_nuts(); >> >> word wrap in tbird can't be turned off, the if/else are really just 2 >> lines. >> from the log window: >> ECHO: 184, 0.3, 0.1 >> ECHO: 184, 0.4, 0 >> ECHO: 184, 0.5, 0.1 >> but if I goto .60, it gets this >> ECHO: 184, 0.6, 5.55112e-17 and from there on, where it s/b 0, its not. >> >> Help, if there is any. >> this is linux AppImage 2023.09.10.ai16125 (git dcaf25f0e) >> >> Cheers, Gene Heskett. >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org Cheers, Gene Heskett. -- "There are four boxes to be used in defense of liberty: soap, ballot, jury, and ammo. Please use in that order." -Ed Howdershelt (Author, 1940) If we desire respect for the law, we must first make the law respectable. - Louis D. Brandeis
SP
Sanjeev Prabhakar
Sat, Nov 11, 2023 4:12 AM

if accuracy up to 10 decimal points is acceptable, this should work in most
of the cases

function rnd(v,n)=round(v*10^n)/10^n;

function mod(a,b)=rnd(a-b*floor(rnd(a/b,10)),10);

echo(mod(.6,.2));

On Fri, 10 Nov 2023 at 20:04, gene heskett via Discuss <
discuss@lists.openscad.org> wrote:

Greetings all;

Attempting to get a true/false in an if statement, I used the ( i % .2)
construct to cause a 180 degree rotation in order to fit more on the
printers plate. But its not working as expected. is the % supposed to
yield a remainder of a division?

This code works for i=.3 to .5 step .1
but fails for i=.3 to .6 or higher
module test_nuts() // will print the first 3 on the e5-s1
{  yofs=15;
for(i=[.30:.10:.50])
{
echo(184,i,(i % .20));
tsz=str(i);
echo(186,tsz);
yloc=(i-.3)*450;
if(i %
.20)translate([20,yofs+yloc-60,0])short_test_newnut(nozzle,3,tsz);
else

translate([195,yofs+yloc+140,0])rotate([0,0,180])short_test_newnut(nozzle,3,tsz);
}
}
test_nuts();

word wrap in tbird can't be turned off, the if/else are really just 2
lines.
from the log window:
ECHO: 184, 0.3, 0.1
ECHO: 184, 0.4, 0
ECHO: 184, 0.5, 0.1
but if I goto .60, it gets this
ECHO: 184, 0.6, 5.55112e-17 and from there on, where it s/b 0, its not.

Help, if there is any.
this is linux AppImage 2023.09.10.ai16125 (git dcaf25f0e)

Cheers, Gene Heskett.

"There are four boxes to be used in defense of liberty:
soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author, 1940)
If we desire respect for the law, we must first make the law respectable.

if accuracy up to 10 decimal points is acceptable, this should work in most of the cases function rnd(v,n)=round(v*10^n)/10^n; function mod(a,b)=rnd(a-b*floor(rnd(a/b,10)),10); echo(mod(.6,.2)); On Fri, 10 Nov 2023 at 20:04, gene heskett via Discuss < discuss@lists.openscad.org> wrote: > Greetings all; > > Attempting to get a true/false in an if statement, I used the ( i % .2) > construct to cause a 180 degree rotation in order to fit more on the > printers plate. But its not working as expected. is the % supposed to > yield a remainder of a division? > > This code works for i=.3 to .5 step .1 > but fails for i=.3 to .6 or higher > module test_nuts() // will print the first 3 on the e5-s1 > { yofs=15; > for(i=[.30:.10:.50]) > { > echo(184,i,(i % .20)); > tsz=str(i); > echo(186,tsz); > yloc=(i-.3)*450; > if(i % > .20)translate([20,yofs+yloc-60,0])short_test_newnut(nozzle,3,tsz); > else > > translate([195,yofs+yloc+140,0])rotate([0,0,180])short_test_newnut(nozzle,3,tsz); > } > } > test_nuts(); > > word wrap in tbird can't be turned off, the if/else are really just 2 > lines. > from the log window: > ECHO: 184, 0.3, 0.1 > ECHO: 184, 0.4, 0 > ECHO: 184, 0.5, 0.1 > but if I goto .60, it gets this > ECHO: 184, 0.6, 5.55112e-17 and from there on, where it s/b 0, its not. > > Help, if there is any. > this is linux AppImage 2023.09.10.ai16125 (git dcaf25f0e) > > Cheers, Gene Heskett. > -- > "There are four boxes to be used in defense of liberty: > soap, ballot, jury, and ammo. Please use in that order." > -Ed Howdershelt (Author, 1940) > If we desire respect for the law, we must first make the law respectable. > - Louis D. Brandeis_______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
SP
Sanjeev Prabhakar
Sat, Nov 11, 2023 7:09 AM

correction (this takes care of sign of 'a' and 'b') :

// function to do rounding a number up to n decimal points
function rnd(v,n)=round(v*10^n)/10^n;

function mod(a,b)=rnd(a-sign(a)/sign(b)bfloor(rnd(abs(a/b),10)),10);

On Sat, 11 Nov 2023 at 09:42, Sanjeev Prabhakar sprabhakar2006@gmail.com
wrote:

if accuracy up to 10 decimal points is acceptable, this should work in
most of the cases

function rnd(v,n)=round(v*10^n)/10^n;

function mod(a,b)=rnd(a-b*floor(rnd(a/b,10)),10);

echo(mod(.6,.2));

On Fri, 10 Nov 2023 at 20:04, gene heskett via Discuss <
discuss@lists.openscad.org> wrote:

Greetings all;

Attempting to get a true/false in an if statement, I used the ( i % .2)
construct to cause a 180 degree rotation in order to fit more on the
printers plate. But its not working as expected. is the % supposed to
yield a remainder of a division?

This code works for i=.3 to .5 step .1
but fails for i=.3 to .6 or higher
module test_nuts() // will print the first 3 on the e5-s1
{  yofs=15;
for(i=[.30:.10:.50])
{
echo(184,i,(i % .20));
tsz=str(i);
echo(186,tsz);
yloc=(i-.3)*450;
if(i %
.20)translate([20,yofs+yloc-60,0])short_test_newnut(nozzle,3,tsz);
else

translate([195,yofs+yloc+140,0])rotate([0,0,180])short_test_newnut(nozzle,3,tsz);
}
}
test_nuts();

word wrap in tbird can't be turned off, the if/else are really just 2
lines.
from the log window:
ECHO: 184, 0.3, 0.1
ECHO: 184, 0.4, 0
ECHO: 184, 0.5, 0.1
but if I goto .60, it gets this
ECHO: 184, 0.6, 5.55112e-17 and from there on, where it s/b 0, its not.

Help, if there is any.
this is linux AppImage 2023.09.10.ai16125 (git dcaf25f0e)

Cheers, Gene Heskett.

"There are four boxes to be used in defense of liberty:
soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author, 1940)
If we desire respect for the law, we must first make the law respectable.

correction (this takes care of sign of 'a' and 'b') : // function to do rounding a number up to n decimal points function rnd(v,n)=round(v*10^n)/10^n; function mod(a,b)=rnd(a-sign(a)/sign(b)*b*floor(rnd(abs(a/b),10)),10); On Sat, 11 Nov 2023 at 09:42, Sanjeev Prabhakar <sprabhakar2006@gmail.com> wrote: > if accuracy up to 10 decimal points is acceptable, this should work in > most of the cases > > function rnd(v,n)=round(v*10^n)/10^n; > > function mod(a,b)=rnd(a-b*floor(rnd(a/b,10)),10); > > echo(mod(.6,.2)); > > On Fri, 10 Nov 2023 at 20:04, gene heskett via Discuss < > discuss@lists.openscad.org> wrote: > >> Greetings all; >> >> Attempting to get a true/false in an if statement, I used the ( i % .2) >> construct to cause a 180 degree rotation in order to fit more on the >> printers plate. But its not working as expected. is the % supposed to >> yield a remainder of a division? >> >> This code works for i=.3 to .5 step .1 >> but fails for i=.3 to .6 or higher >> module test_nuts() // will print the first 3 on the e5-s1 >> { yofs=15; >> for(i=[.30:.10:.50]) >> { >> echo(184,i,(i % .20)); >> tsz=str(i); >> echo(186,tsz); >> yloc=(i-.3)*450; >> if(i % >> .20)translate([20,yofs+yloc-60,0])short_test_newnut(nozzle,3,tsz); >> else >> >> translate([195,yofs+yloc+140,0])rotate([0,0,180])short_test_newnut(nozzle,3,tsz); >> } >> } >> test_nuts(); >> >> word wrap in tbird can't be turned off, the if/else are really just 2 >> lines. >> from the log window: >> ECHO: 184, 0.3, 0.1 >> ECHO: 184, 0.4, 0 >> ECHO: 184, 0.5, 0.1 >> but if I goto .60, it gets this >> ECHO: 184, 0.6, 5.55112e-17 and from there on, where it s/b 0, its not. >> >> Help, if there is any. >> this is linux AppImage 2023.09.10.ai16125 (git dcaf25f0e) >> >> Cheers, Gene Heskett. >> -- >> "There are four boxes to be used in defense of liberty: >> soap, ballot, jury, and ammo. Please use in that order." >> -Ed Howdershelt (Author, 1940) >> If we desire respect for the law, we must first make the law respectable. >> - Louis D. Brandeis_______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> >
RW
Rogier Wolff
Sat, Nov 11, 2023 8:04 PM

On Fri, Nov 10, 2023 at 08:18:13PM -0500, gene heskett via Discuss wrote:

Ok, I've done that and it works up to a final target of .90 but
fails for target values of 1.0 and up.  So what I and going to do is
use that basic code and add an offset to the var i to make the rest
of this up to about 4.0. What I'm making is a gauge set, with the
buttress thread increasing from a starter value to that + the amount
printed on the tab.

In openscad it might be better to just structure your loops with an
integer as a loop parameter if you want to do this kind of stuff.

So instead of:

for (x=[.10:.10:1.5])
for (y=[.15:.15:1.5]) {
if (x % .20) ...
}

you do:

for (ix=[1:1:15])
for (iy=[1:1:10]) {
x = ix * .10;
y = iy * .15
if (ix % 2) ...
}

Roger.

--
** R.E.Wolff@BitWizard.nl ** https://www.BitWizard.nl/ ** +31-15-2049110 **
**    Delftechpark 11 2628 XJ  Delft, The Netherlands.  KVK: 27239233    **
f equals m times a. When your f is steady, and your m is going down
your a is going up.  -- Chris Hadfield about flying up the space shuttle.

On Fri, Nov 10, 2023 at 08:18:13PM -0500, gene heskett via Discuss wrote: > Ok, I've done that and it works up to a final target of .90 but > fails for target values of 1.0 and up. So what I and going to do is > use that basic code and add an offset to the var i to make the rest > of this up to about 4.0. What I'm making is a gauge set, with the > buttress thread increasing from a starter value to that + the amount > printed on the tab. In openscad it might be better to just structure your loops with an integer as a loop parameter if you want to do this kind of stuff. So instead of: for (x=[.10:.10:1.5]) for (y=[.15:.15:1.5]) { if (x % .20) ... } you do: for (ix=[1:1:15]) for (iy=[1:1:10]) { x = ix * .10; y = iy * .15 if (ix % 2) ... } Roger. -- ** R.E.Wolff@BitWizard.nl ** https://www.BitWizard.nl/ ** +31-15-2049110 ** ** Delftechpark 11 2628 XJ Delft, The Netherlands. KVK: 27239233 ** f equals m times a. When your f is steady, and your m is going down your a is going up. -- Chris Hadfield about flying up the space shuttle.