R
runsun
Thu, Nov 12, 2015 5:35 PM
Just encountered an odd thing. The process is simple: add 0.1 and 0.02, to
see if it equals 0.12.
echo( 1/10 == 0.1 ); // true
echo( 2/100 == 0.02 ); // true
echo( 1/10 + 2/100 == 0.12 ); // false <===== duhh ???
How come 1/10 and 2/100 both are accurate, but not if they are added ?
It seems that a simple operation of addition introduces error:
echo( (1/10 + 2/100 - 0.12)*pow(10,10) ) ==> 1.38778e-07
I tried several other numbers but only 0.12 goes wrong.
This means that if you have code like:
a = some_value;
b = some_other_value;
c = value a + b;
A boolean check like c==a+b? would give false negative some time but not all
the time, which would be extremely hard to debug.
$ 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-tp14408.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
Just encountered an odd thing. The process is simple: add 0.1 and 0.02, to
see if it equals 0.12.
> echo( 1/10 == 0.1 ); // true
> echo( 2/100 == 0.02 ); // true
> echo( 1/10 + 2/100 == 0.12 ); // false <===== duhh ???
How come 1/10 and 2/100 both are accurate, but not if they are added ?
It seems that a simple operation of addition introduces error:
> echo( (1/10 + 2/100 - 0.12)*pow(10,10) ) ==> 1.38778e-07
I tried several other numbers but only 0.12 goes wrong.
This means that if you have code like:
> a = some_value;
> b = some_other_value;
> c = value a + b;
A boolean check like c==a+b? would give false negative some time but not all
the time, which would be extremely hard to debug.
-----
$ 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-tp14408.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
YA
Yona Appletree
Thu, Nov 12, 2015 6:12 PM
Runsun,
This is due to the inherent nature of floating point numbers. Not all
values can be represented exactly, and this behavior is quite standard.
It's generally not advised to do equality checks on floats... you should
always use a range check.
This does basically the same thing in javascript:
node
runsun mailto:runsun@gmail.com
November 12, 2015 at 09:35
Just encountered an odd thing. The process is simple: add 0.1 and 0.02, to
see if it equals 0.12.
echo( 1/10 == 0.1 ); // true
echo( 2/100 == 0.02 ); // true
echo( 1/10 + 2/100 == 0.12 ); // false<===== duhh ???
How come 1/10 and 2/100 both are accurate, but not if they are added ?
It seems that a simple operation of addition introduces error:
echo( (1/10 + 2/100 - 0.12)*pow(10,10) ) ==> 1.38778e-07
I tried several other numbers but only 0.12 goes wrong.
This means that if you have code like:
a = some_value;
b = some_other_value;
c = value a + b;
A boolean check like c==a+b? would give false negative some time but not all
the time, which would be extremely hard to debug.
$ 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-tp14408.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
Runsun,
This is due to the inherent nature of floating point numbers. Not all
values can be represented exactly, and this behavior is quite standard.
It's generally not advised to do equality checks on floats... you should
always use a range check.
This does basically the same thing in javascript:
# node
> .1 + .02
0.12000000000000001
> .1 + .02 == .12
false
- Yona
> runsun <mailto:runsun@gmail.com>
> November 12, 2015 at 09:35
> Just encountered an odd thing. The process is simple: add 0.1 and 0.02, to
> see if it equals 0.12.
>
>> echo( 1/10 == 0.1 ); // true
>> echo( 2/100 == 0.02 ); // true
>> echo( 1/10 + 2/100 == 0.12 ); // false<===== duhh ???
>
> How come 1/10 and 2/100 both are accurate, but not if they are added ?
>
> It seems that a simple operation of addition introduces error:
>
>> echo( (1/10 + 2/100 - 0.12)*pow(10,10) ) ==> 1.38778e-07
>
> I tried several other numbers but only 0.12 goes wrong.
>
> This means that if you have code like:
>
>> a = some_value;
>> b = some_other_value;
>> c = value a + b;
>
> A boolean check like c==a+b? would give false negative some time but not all
> the time, which would be extremely hard to debug.
>
>
>
>
> -----
>
> $ 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-tp14408.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
R
runsun
Thu, Nov 12, 2015 6:27 PM
Thx Hypher. Good to know.
I have a unit test lib in which comparing two values is essential, so
floating point comparison is unavoidable. Guess I'll have to resolve it in
some other way.
$ 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-tp14408p14411.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
Thx Hypher. Good to know.
I have a unit test lib in which comparing two values is essential, so
floating point comparison is unavoidable. Guess I'll have to resolve it in
some other way.
-----
$ 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-tp14408p14411.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
AC
Alan Cox
Thu, Nov 12, 2015 6:42 PM
Thx Hypher. Good to know.
I have a unit test lib in which comparing two values is essential, so
floating point comparison is unavoidable. Guess I'll have to resolve it in
some other way.
The usual approach would be
abs(a - b) < ACCEPTABLE_ERROR
Whether adding an ~= operator to OpenSCAD would be helpful I don't know.
It's difficult to define "approximately" in a way that works for every
use.
Alan
On Thu, 12 Nov 2015 11:27:22 -0700 (MST)
runsun <runsun@gmail.com> wrote:
> Thx Hypher. Good to know.
>
> I have a unit test lib in which comparing two values is essential, so
> floating point comparison is unavoidable. Guess I'll have to resolve it in
> some other way.
The usual approach would be
abs(a - b) < ACCEPTABLE_ERROR
Whether adding an ~= operator to OpenSCAD would be helpful I don't know.
It's difficult to define "approximately" in a way that works for every
use.
Alan
RW
Rob Ward
Thu, Nov 12, 2015 9:07 PM
On 13/11/15 05:42, Alan Cox wrote:
Thx Hypher. Good to know.
I have a unit test lib in which comparing two values is essential, so
floating point comparison is unavoidable. Guess I'll have to resolve it in
some other way.
Could there be a setting like the $fn=20; to control 'smoothness', and
have it set the level of 'approximation',
therefore the feature is available and "let the user beware"?
$fa=0.001; //floating point resolved to within 0.001%
If this was localised to within modules, it could be turned off and on
as required??
Rob
On 13/11/15 05:42, Alan Cox wrote:
> On Thu, 12 Nov 2015 11:27:22 -0700 (MST)
> runsun <runsun@gmail.com> wrote:
>
>> Thx Hypher. Good to know.
>>
>> I have a unit test lib in which comparing two values is essential, so
>> floating point comparison is unavoidable. Guess I'll have to resolve it in
>> some other way.
> The usual approach would be
>
> abs(a - b) < ACCEPTABLE_ERROR
>
> Whether adding an ~= operator to OpenSCAD would be helpful I don't know.
> It's difficult to define "approximately" in a way that works for every
> use.
>
> Alan
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
Could there be a setting like the $fn=20; to control 'smoothness', and
have it set the level of 'approximation',
therefore the feature is available and "let the user beware"?
$fa=0.001; //floating point resolved to within 0.001%
If this was localised to within modules, it could be turned off and on
as required??
Rob
RW
Rob Ward
Thu, Nov 12, 2015 9:19 PM
On 13/11/15 04:35, runsun wrote:
Just encountered an odd thing. The process is simple: add 0.1 and 0.02, to
see if it equals 0.12.
echo( 1/10 == 0.1 ); // true
echo( 2/100 == 0.02 ); // true
echo( 1/10 + 2/100 == 0.12 ); // false <===== duhh ???
How come 1/10 and 2/100 both are accurate, but not if they are added ?
It seems that a simple operation of addition introduces error:
echo( (1/10 + 2/100 - 0.12)*pow(10,10) ) ==> 1.38778e-07
I tried several other numbers but only 0.12 goes wrong.
This means that if you have code like:
a = some_value;
b = some_other_value;
c = value a + b;
A boolean check like c==a+b? would give false negative some time but not all
the time, which would be extremely hard to debug.
$ 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-tp14408.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
echo( (1/10 + 2/100) ==0.12); // also reports false???
echo( (1/10 + 2/100)) //produces 0.12, curious and curious-er!!
Rob
On 13/11/15 04:35, runsun wrote:
> Just encountered an odd thing. The process is simple: add 0.1 and 0.02, to
> see if it equals 0.12.
>
>> echo( 1/10 == 0.1 ); // true
>> echo( 2/100 == 0.02 ); // true
>> echo( 1/10 + 2/100 == 0.12 ); // false <===== duhh ???
> How come 1/10 and 2/100 both are accurate, but not if they are added ?
>
> It seems that a simple operation of addition introduces error:
>
>> echo( (1/10 + 2/100 - 0.12)*pow(10,10) ) ==> 1.38778e-07
> I tried several other numbers but only 0.12 goes wrong.
>
> This means that if you have code like:
>
>> a = some_value;
>> b = some_other_value;
>> c = value a + b;
> A boolean check like c==a+b? would give false negative some time but not all
> the time, which would be extremely hard to debug.
>
>
>
>
> -----
>
> $ 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-tp14408.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
>
echo( (1/10 + 2/100) ==0.12); // also reports false???
echo( (1/10 + 2/100)) //produces 0.12, curious and curious-er!!
Rob
NH
nop head
Thu, Nov 12, 2015 9:45 PM
0.1 and 0.02 are infinitely recurring numbers in binary so that is why they
are never equal in finite word length arithmetic. In general a lot more
fractions are not exact in binary.
echo() does some rounding, which is why it gives 0.12.
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
On 12 November 2015 at 21:19, Rob Ward rl.ward@bigpond.com wrote:
On 13/11/15 04:35, runsun wrote:
Just encountered an odd thing. The process is simple: add 0.1 and 0.02, to
see if it equals 0.12.
echo( 1/10 == 0.1 ); // true
echo( 2/100 == 0.02 ); // true
echo( 1/10 + 2/100 == 0.12 ); // false <===== duhh ???
How come 1/10 and 2/100 both are accurate, but not if they are added ?
It seems that a simple operation of addition introduces error:
echo( (1/10 + 2/100 - 0.12)*pow(10,10) ) ==> 1.38778e-07
I tried several other numbers but only 0.12 goes wrong.
This means that if you have code like:
a = some_value;
b = some_other_value;
c = value a + b;
A boolean check like c==a+b? would give false negative some time but not
all
the time, which would be extremely hard to debug.
$ 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-tp14408.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
echo( (1/10 + 2/100) ==0.12); // also reports false???
0.1 and 0.02 are infinitely recurring numbers in binary so that is why they
are never equal in finite word length arithmetic. In general a lot more
fractions are not exact in binary.
echo() does some rounding, which is why it gives 0.12.
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
On 12 November 2015 at 21:19, Rob Ward <rl.ward@bigpond.com> wrote:
> On 13/11/15 04:35, runsun wrote:
>
>> Just encountered an odd thing. The process is simple: add 0.1 and 0.02, to
>> see if it equals 0.12.
>>
>> echo( 1/10 == 0.1 ); // true
>>> echo( 2/100 == 0.02 ); // true
>>> echo( 1/10 + 2/100 == 0.12 ); // false <===== duhh ???
>>>
>> How come 1/10 and 2/100 both are accurate, but not if they are added ?
>>
>> It seems that a simple operation of addition introduces error:
>>
>> echo( (1/10 + 2/100 - 0.12)*pow(10,10) ) ==> 1.38778e-07
>>>
>> I tried several other numbers but only 0.12 goes wrong.
>>
>> This means that if you have code like:
>>
>> a = some_value;
>>> b = some_other_value;
>>> c = value a + b;
>>>
>> A boolean check like c==a+b? would give false negative some time but not
>> all
>> the time, which would be extremely hard to debug.
>>
>>
>>
>>
>> -----
>>
>> $ 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-tp14408.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
>>
>> echo( (1/10 + 2/100) ==0.12); // also reports false???
> echo( (1/10 + 2/100)) //produces 0.12, curious and curious-er!!
>
>
> Rob
>
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
C
ctchin
Fri, Nov 13, 2015 2:37 AM
I encounter this im a very real world way when replicating an object. I was
making a
ring of LED's and was shocked when I can't reliably make an integer number
of LED
around a circle.
Digging, I created this demo call nasty.scad :
The lesson is that you have to be very careful and deliberate setting the
end value of for() loops.
--
View this message in context: http://forum.openscad.org/Simple-addition-of-numbers-introduces-error-tp14408p14430.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
I encounter this im a very real world way when replicating an object. I was
making a
ring of LED's and was shocked when I can't reliably make an integer number
of LED
around a circle.
Digging, I created this demo call nasty.scad :
The lesson is that you have to be very careful and deliberate setting the
end value of for() loops.
--
View this message in context: http://forum.openscad.org/Simple-addition-of-numbers-introduces-error-tp14408p14430.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
R
runsun
Fri, Nov 13, 2015 10:44 PM
The usual approach would be
abs(a - b) < ACCEPTABLE_ERROR
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.
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.
R
runsun
Fri, Nov 13, 2015 10:49 PM
@ ctchin,
Thx. Your nasty.scad helps to show that it's better not use a fraction as
the step in a for=[beg:step:end] manner. Good to know.
$ 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-tp14408p14465.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
@ ctchin,
Thx. Your nasty.scad helps to show that it's better not use a fraction as
the step in a for=[beg:step:end] manner. Good to know.
-----
$ 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-tp14408p14465.html
Sent from the OpenSCAD mailing list archive at Nabble.com.