Annoying math inaccuracy

Hi there,
any way to get around this math inaccuracy (using GNU/RTP):

If you do

double a = 1;

while (1)
{
cout << a << endl;
a -= 0.1;
}

You get

1
0.9
0.8

0.2
0.1
1.38778e-16
-0.1
-0.2


Thanks
Markus

Markus Loffler <loffler@ces.clemson.edu> wrote:

Hi there,
any way to get around this math inaccuracy (using GNU/RTP):

Probably not – this is inherent in how fractions are represent
in binary. This is one of the reasons why you should never test for
the result of a floating point operation being equal to some value.
It should always be ( abs(result - value) < delta).

If you do

double a = 1;

while (1)
{
cout << a << endl;
a -= 0.1;
}

You get

1
0.9
0.8

0.2
0.1
1.38778e-16

I’ll bet you that all of the other values are off by equivalent ammounts
to the 0 case – but the output library rounds them nicely since they are
something like .100000000000000x, but when it is 0.000000000x, there is
no “leading” number to suggest where the precision should be.

So, are you worried about pretty output? In that case, use an
explicit output format for your number – it will then get rounded
as expected. If you are worried about the actual accuracy… see my
statement at the top. (That is, you can’t get it. Think about
“decimal” values – can you accurately represent the value of 1/3
in a finite length decimal? Of course not. Well, 0.1 is 1/10,
which can be accurately represent in a base 10 decimal, but can not
be accurately represented in base 2.)

-David


QNX Training Services
dagibbs@qnx.com

static const double step = 0.1;
static int ndx = 20;
while (ndx–) {
cout<<(ndx-9)*step<<end;
}

Markus Loffler wrote:

Hi there,
any way to get around this math inaccuracy (using GNU/RTP):

If you do

double a = 1;

while (1)
{
cout << a << endl;
a -= 0.1;
}

You get

1
0.9
0.8

0.2
0.1
1.38778e-16
-0.1
-0.2


Thanks
Markus

“David Gibbs” <dagibbs@qnx.com> wrote in message
news:99djie$d3p$7@nntp.qnx.com

Markus Loffler <> loffler@ces.clemson.edu> > wrote:
Hi there,
any way to get around this math inaccuracy (using GNU/RTP):

Probably not – this is inherent in how fractions are represent
in binary. This is one of the reasons why you should never test for
the result of a floating point operation being equal to some value.
It should always be ( abs(result - value) < delta).

Hi David.

Do you mean (abs(result - value) < delta) or (fabs(result - value) < delta)?

How does this work?

Thanks

Augie


If you do

double a = 1;

while (1)
{
cout << a << endl;
a -= 0.1;
}

You get

1
0.9
0.8

0.2
0.1
1.38778e-16

I’ll bet you that all of the other values are off by equivalent ammounts
to the 0 case – but the output library rounds them nicely since they are
something like .100000000000000x, but when it is 0.000000000x, there is
no “leading” number to suggest where the precision should be.

So, are you worried about pretty output? In that case, use an
explicit output format for your number – it will then get rounded
as expected. If you are worried about the actual accuracy… see my
statement at the top. (That is, you can’t get it. Think about
“decimal” values – can you accurately represent the value of 1/3
in a finite length decimal? Of course not. Well, 0.1 is 1/10,
which can be accurately represent in a base 10 decimal, but can not
be accurately represented in base 2.)

-David


QNX Training Services
dagibbs@qnx.com

Augie Henriques <augiehenriques@hotmail.com> wrote:

“David Gibbs” <> dagibbs@qnx.com> > wrote in message
news:99djie$d3p$> 7@nntp.qnx.com> …
Markus Loffler <> loffler@ces.clemson.edu> > wrote:
Hi there,
any way to get around this math inaccuracy (using GNU/RTP):

Probably not – this is inherent in how fractions are represent
in binary. This is one of the reasons why you should never test for
the result of a floating point operation being equal to some value.
It should always be ( abs(result - value) < delta).

Hi David.

Do you mean (abs(result - value) < delta) or (fabs(result - value) < delta)?

I was talking pseudo-code, actually, rather than implying any particular
function from the C library. You are quite correct that it should be
fabs() [float] rather than abs() [integer] in the standard C library.

-David

QNX Training Services
dagibbs@qnx.com