discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Simple addition of numbers introduces error

DM
doug moen
Fri, Nov 13, 2015 11:03 PM

Alan's approach for testing equality within a tolerance is the recommended
approach. It lets you specify a tolerance, and can (in principle) be
compiled into fast code (once we have a proper JIT compiler).

Nophead's approach is not recommended. It will break once we fix the
float->string conversion, as is being discussed elsewhere in the forum. You
can't specify a tolerance, and it will be slower in compiled code.

On 13 November 2015 at 17:44, runsun runsun@gmail.com wrote:

Alan Cox wrote

The usual approach would be

   abs(a - b) < ACCEPTABLE_ERROR

nophead wrote

Perhaps runsun could convert to strings with str to compare them. E.g.

x = 0.1 + 0.02;

echo(x == 0.12);
echo(str(x) == "0.12");

ECHO: false
ECHO: true

Thx to Alan and nophead. Both approaches are in fact used in my doctest lib
already. It's just that after months of success, something tickling (or
breaking) my brain cells, let me start suspecting that it is not quite
right
yet.

I now see that Openscad uses 17 significant digits for the internal
operations, and 6 digits for display. I'll have to think about if my lib
needs to change based on this findings.


$  Runsun Pan, PhD

$ libs: doctest , faces ( git ), offline doc ( git ),runscad.py( 1 , 2 ,
git );

$ tips: hash( 1 , 2 ), sweep , var , lerp , animGif

--
View this message in context:
http://forum.openscad.org/Simple-addition-of-numbers-introduces-error-tp14408p14464.html
Sent from the OpenSCAD mailing list archive at Nabble.com.


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

Alan's approach for testing equality within a tolerance is the recommended approach. It lets you specify a tolerance, and can (in principle) be compiled into fast code (once we have a proper JIT compiler). Nophead's approach is not recommended. It will break once we fix the float->string conversion, as is being discussed elsewhere in the forum. You can't specify a tolerance, and it will be slower in compiled code. On 13 November 2015 at 17:44, runsun <runsun@gmail.com> wrote: > Alan Cox wrote > > The usual approach would be > > > > abs(a - b) < ACCEPTABLE_ERROR > > > nophead wrote > > Perhaps runsun could convert to strings with str to compare them. E.g. > > > > x = 0.1 + 0.02; > > > > echo(x == 0.12); > > echo(str(x) == "0.12"); > > > > ECHO: false > > ECHO: true > > Thx to Alan and nophead. Both approaches are in fact used in my doctest lib > already. It's just that after months of success, something tickling (or > breaking) my brain cells, let me start suspecting that it is not quite > right > yet. > > I now see that Openscad uses 17 significant digits for the internal > operations, and 6 digits for display. I'll have to think about if my lib > needs to change based on this findings. > > > > ----- > > $ Runsun Pan, PhD > > $ libs: doctest , faces ( git ), offline doc ( git ),runscad.py( 1 , 2 , > git ); > > $ tips: hash( 1 , 2 ), sweep , var , lerp , animGif > > > > > > > -- > View this message in context: > http://forum.openscad.org/Simple-addition-of-numbers-introduces-error-tp14408p14464.html > Sent from the OpenSCAD mailing list archive at Nabble.com. > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > > >
LB
L Boyd
Sat, Nov 14, 2015 8:23 PM

// so... should the following makes 25 or 26 balls?
for (i=[0:0.2:5]) {
translate([0,i*10,0]) sphere(1.5);
}
fails to give the desired 26 balls because 0.2 can not be represented
exactly in floating point. Whole numbers can be, but most decimal fractions
don't translate exactly into binary.

However this does exactly what you want:

for (i=[0:0.2:5.001) translate([0,i*10,0]) sphere(1.5);

or even better:

for (i=[0:2:50) translate([0,i,0]) sphere(1.5);

--
View this message in context: http://forum.openscad.org/Simple-addition-of-numbers-introduces-error-tp14408p14483.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

// so... should the following makes 25 or 26 balls? for (i=[0:0.2:5]) { translate([0,i*10,0]) sphere(1.5); } fails to give the desired 26 balls because 0.2 can not be represented exactly in floating point. Whole numbers can be, but most decimal fractions don't translate exactly into binary. However this does exactly what you want: for (i=[0:0.2:5.001) translate([0,i*10,0]) sphere(1.5); or even better: for (i=[0:2:50) translate([0,i,0]) sphere(1.5); -- View this message in context: http://forum.openscad.org/Simple-addition-of-numbers-introduces-error-tp14408p14483.html Sent from the OpenSCAD mailing list archive at Nabble.com.
R
runsun
Fri, Nov 20, 2015 6:49 PM

runsun wrote

Alan Cox wrote

The usual approach would be
abs(a - b) < ACCEPTABLE_ERROR

nophead wrote

Perhaps runsun could convert to strings with str to compare them. E.g.

x = 0.1 + 0.02;

echo(x == 0.12);
echo(str(x) == "0.12");

ECHO: false
ECHO: true

Thx to Alan and nophead. Both approaches are in fact used in my doctest
lib already. It's just that after months of success, something tickling
(or breaking) my brain cells, let me start suspecting that it is not quite
right yet.

I now see that Openscad uses 17 significant digits for the internal
operations, and 6 digits for display. I'll have to think about if my lib
needs to change based on this findings.

Found a 3rd way to solve this. This potentially eliminates the error caused
by binary rounding:

echo( 0.1+0.02 == 0.12 );  // false
f = pow(10,10);
echo( (0.1f+0.02f)/f == 0.12 ); // true

I.e., multiply it by a big number to kind of raise it up some order, do the
addition/subtraction, then bring it back down to the original order.


$  Runsun Pan, PhD

$ libs:

doctest ,

faces ( git ),

offline doc ( git ),

runscad.py( 1 , 2 , git );

$ tips:

hash( 1 , 2 ),

sweep ,

var( 1 , 2 ),

lerp ,

animGif ,

precision

--
View this message in context: http://forum.openscad.org/Simple-addition-of-numbers-introduces-error-tp14408p14676.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

runsun wrote > > Alan Cox wrote >> The usual approach would be >> abs(a - b) < ACCEPTABLE_ERROR > > nophead wrote >> Perhaps runsun could convert to strings with str to compare them. E.g. >> >> x = 0.1 + 0.02; >> >> echo(x == 0.12); >> echo(str(x) == "0.12"); >> >> ECHO: false >> ECHO: true > Thx to Alan and nophead. Both approaches are in fact used in my doctest > lib already. It's just that after months of success, something tickling > (or breaking) my brain cells, let me start suspecting that it is not quite > right yet. > > I now see that Openscad uses 17 significant digits for the internal > operations, and 6 digits for display. I'll have to think about if my lib > needs to change based on this findings. Found a 3rd way to solve this. This potentially eliminates the error caused by binary rounding: > echo( 0.1+0.02 == 0.12 ); // false > f = pow(10,10); > echo( (0.1*f+0.02*f)/f == 0.12 ); // true I.e., multiply it by a big number to kind of raise it up some order, do the addition/subtraction, then bring it back down to the original order. ----- $ Runsun Pan, PhD $ libs: doctest , faces ( git ), offline doc ( git ), runscad.py( 1 , 2 , git ); $ tips: hash( 1 , 2 ), sweep , var( 1 , 2 ), lerp , animGif , precision -- View this message in context: http://forum.openscad.org/Simple-addition-of-numbers-introduces-error-tp14408p14676.html Sent from the OpenSCAD mailing list archive at Nabble.com.