Velocity Reviews > C++ > Deviation of double

# Deviation of double

Christian Meier
Guest
Posts: n/a

 05-17-2004
Hallo NG

My problem is the deviation of the floating point datatypes. 90.625 is not
exactly 90.625. It is 90.624999999.... on my system. Now I tried to find a
solution for my problem but I couldn't think of one. So I tried to write a
work-arround which should solve the problem for the most numbers.
What do you think of this: (I know it is not a perfect solution....)

double dValue = ...;

if (dValue >= 10000000000000LL) {
nInValue += 0.01;
} else if (dValue >= 1000000000000LL) {
nInValue += 0.001;
} else if (dValue >= 100000000000LL) {
nInValue += 0.0001;
} else if (dValue >= 10000000000LL) {
nInValue += 0.00001;
} else if (dValue >= 1000000000) {
nInValue += 0.000001;
} else if (dValue >= 100000000) {
nInValue += 0.0000001;
} else if (dValue >= 10000000) {
nInValue += 0.00000001;
} else if (dValue >= 1000000) {
nInValue += 0.000000001;
} else if (dValue >= 100000) {
nInValue += 0.0000000001;
} else if (dValue >= 10000) {
nInValue += 0.00000000001;
} else if (dValue >= 1000) {
nInValue += 0.000000000001;
} else if (dValue >= 100) {
nInValue += 0.0000000000001;
} else if (dValue >= 10) {
nInValue += 0.00000000000001;
} else if (dValue < 0) {
nInValue -= 0.000000000000001;
} // if

Greets Chris

Peter van Merkerk
Guest
Posts: n/a

 05-17-2004

"Christian Meier" <(E-Mail Removed)> wrote in message
news:c8aaoj\$htb\$(E-Mail Removed)...
> Hallo NG
>
> My problem is the deviation of the floating point datatypes. 90.625 is

not
> exactly 90.625. It is 90.624999999.... on my system. Now I tried to find

a
> solution for my problem but I couldn't think of one. So I tried to write

a
> work-arround which should solve the problem for the most numbers.
> What do you think of this: (I know it is not a perfect solution....)
>
> double dValue = ...;
>
> if (dValue >= 10000000000000LL) {
> nInValue += 0.01;
> } else if (dValue >= 1000000000000LL) {
> nInValue += 0.001;
> } else if (dValue >= 100000000000LL) {
> nInValue += 0.0001;
> } else if (dValue >= 10000000000LL) {
> nInValue += 0.00001;
> } else if (dValue >= 1000000000) {
> nInValue += 0.000001;
> } else if (dValue >= 100000000) {
> nInValue += 0.0000001;
> } else if (dValue >= 10000000) {
> nInValue += 0.00000001;
> } else if (dValue >= 1000000) {
> nInValue += 0.000000001;
> } else if (dValue >= 100000) {
> nInValue += 0.0000000001;
> } else if (dValue >= 10000) {
> nInValue += 0.00000000001;
> } else if (dValue >= 1000) {
> nInValue += 0.000000000001;
> } else if (dValue >= 100) {
> nInValue += 0.0000000000001;
> } else if (dValue >= 10) {
> nInValue += 0.00000000000001;
> } else if (dValue < 0) {
> nInValue -= 0.000000000000001;
> } // if
>

I'm not sure what you are trying to achieve by doing this, and what about
negative numbers? The problem is that many numbers cannot be exactly
represented in floating point format, just like 1/3 cannot be exactly
represented with just decimal numbers. Fiddling with floating point values
will only help in very specific cases at best. If the inevitable rounding
errors of floating point numbers is not acceptable for your application,
maybe a fixed point format is more appropriate for your application.

--
Peter van Merkerk
peter.van.merkerk(at)dse.nl

Karl Heinz Buchegger
Guest
Posts: n/a

 05-17-2004
Christian Meier wrote:
>
> Hallo NG
>
> My problem is the deviation of the floating point datatypes. 90.625 is not
> exactly 90.625. It is 90.624999999.... on my system. Now I tried to find a
> solution for my problem but I couldn't think of one.

Forgive me. What was your problem?

> So I tried to write a
> work-arround which should solve the problem for the most numbers.
> What do you think of this: (I know it is not a perfect solution....)

I doesn't look like solution to anything.

--
Karl Heinz Buchegger
http://www.velocityreviews.com/forums/(E-Mail Removed)

bartek
Guest
Posts: n/a

 05-17-2004
"Christian Meier" <(E-Mail Removed)> wrote in
news:c8aaoj\$htb\$(E-Mail Removed):

> Hallo NG
>
> My problem is the deviation of the floating point datatypes. 90.625 is
> not exactly 90.625. It is 90.624999999.... on my system. Now I tried
> to find a solution for my problem but I couldn't think of one. So I
> tried to write a work-arround which should solve the problem for the
> most numbers. What do you think of this: (I know it is not a perfect
> solution....)

(...)

You can't "work around" the floating point precision limitation. You can
only use more bits to have a better approximation. An exact representation
would require an infinite amount of bits, wouldn't it?
That's how computers work, sorry.

You can use a specialised extended-precision arithmetics library, though,
like the GNU MP http://www.swox.com/gmp/ for example.

--
:: bartekd [at] o2 [dot] pl

Victor Bazarov
Guest
Posts: n/a

 05-17-2004
bartek wrote:
> [...]
> You can't "work around" the floating point precision limitation.

Yes, he can (and often should). He could use fractions. 90.625 is 725/8.
If all arithmetic operations are done in fractions, it's possible to
achieve exact solution (using large enough integers to represent the numbers).

BTW, to the OP: I have a hard time believing that 90 5/8 is not
represented precisely on your machine. It's quite possible that you
_expect_ it to be represented precisely, like after multiplying 0.90625
with 100, but you don't have your 0.90625 precisely to begin with. That's
the problem, I believe.

V

Christian Meier
Guest
Posts: n/a

 05-17-2004

"Karl Heinz Buchegger" <(E-Mail Removed)> schrieb im Newsbeitrag
news:(E-Mail Removed)...
> Christian Meier wrote:
> >
> > Hallo NG
> >
> > My problem is the deviation of the floating point datatypes. 90.625 is

not
> > exactly 90.625. It is 90.624999999.... on my system. Now I tried to find

a
> > solution for my problem but I couldn't think of one.

>
> Forgive me. What was your problem?
>
> > So I tried to write a
> > work-arround which should solve the problem for the most numbers.
> > What do you think of this: (I know it is not a perfect solution....)

>
> I doesn't look like solution to anything.
>
> --
> Karl Heinz Buchegger
> (E-Mail Removed)

Sorry, wasn't a really good description of my problem. I will give more
infos: I have a function with two parameters. One of type double, the other
one is an int.
string func (double dValue, int iDigits);
This function must return a string which represents the double value.
iDigits is the number of digits after the point. For this I use sprintf. And
now I got a problem. When passing 90.625 to the function (iDigits = 2) then
the function returned 90.62 instead of 90.63. I found out that the double is
stored as 90.624999999... on my system. So I need a solution for this. The
function has to return 90.63. So I thought I can add a small value to dValue
before rounding. And the double has a limit of 15 decimal digits on my
system. So I tried to write a work-arround as described in my first post.
Can you now understand my problem?

Regards,
Chris

Christian Meier
Guest
Posts: n/a

 05-17-2004

"Victor Bazarov" <(E-Mail Removed)> schrieb im Newsbeitrag
news:Cu3qc.230\$(E-Mail Removed)...
> bartek wrote:
> > [...]
> > You can't "work around" the floating point precision limitation.

>
> Yes, he can (and often should). He could use fractions. 90.625 is 725/8.
> If all arithmetic operations are done in fractions, it's possible to
> achieve exact solution (using large enough integers to represent the

numbers).
>
> BTW, to the OP: I have a hard time believing that 90 5/8 is not
> represented precisely on your machine. It's quite possible that you
> _expect_ it to be represented precisely, like after multiplying 0.90625
> with 100, but you don't have your 0.90625 precisely to begin with. That's
> the problem, I believe.
>
> V

It does..... these lines:

double d = 90.625;
char c[10];
sprintf(c, "%.2f", h);
std::cout << c << std::endl;

return the following output:
90.62

Greetings Chris

Karl Heinz Buchegger
Guest
Posts: n/a

 05-17-2004
Victor Bazarov wrote:
>
> bartek wrote:
> > [...]
> > You can't "work around" the floating point precision limitation.

>
> Yes, he can (and often should). He could use fractions. 90.625 is 725/8.
> If all arithmetic operations are done in fractions, it's possible to
> achieve exact solution (using large enough integers to represent the numbers).
>

Hmm. I wonder how you would represent PI in such a system

--
Karl Heinz Buchegger
(E-Mail Removed)

Victor Bazarov
Guest
Posts: n/a

 05-17-2004
Karl Heinz Buchegger wrote:
> Victor Bazarov wrote:
>
>>bartek wrote:
>>
>>>[...]
>>>You can't "work around" the floating point precision limitation.

>>
>>Yes, he can (and often should). He could use fractions. 90.625 is 725/8.
>> If all arithmetic operations are done in fractions, it's possible to
>>achieve exact solution (using large enough integers to represent the numbers).
>>

>
>
> Hmm. I wonder how you would represent PI in such a system

22/7 of course (Gods know a better value). On a serious note, however, I
suspect that the OP starts with integral values. If that's so, then the
result should be representable as a fractional value, if all operations
are arithmetic.

V

Victor Bazarov
Guest
Posts: n/a

 05-17-2004
Christian Meier wrote:
> "Victor Bazarov" <(E-Mail Removed)> schrieb im Newsbeitrag
> news:Cu3qc.230\$(E-Mail Removed)...
>
>>bartek wrote:
>>
>>>[...]
>>>You can't "work around" the floating point precision limitation.

>>
>>Yes, he can (and often should). He could use fractions. 90.625 is 725/8.
>> If all arithmetic operations are done in fractions, it's possible to
>>achieve exact solution (using large enough integers to represent the

>
> numbers).
>
>>BTW, to the OP: I have a hard time believing that 90 5/8 is not
>>represented precisely on your machine. It's quite possible that you
>>_expect_ it to be represented precisely, like after multiplying 0.90625
>>with 100, but you don't have your 0.90625 precisely to begin with. That's
>>the problem, I believe.
>>
>>V

>
>
> It does..... these lines:
>
> double d = 90.625;
> char c[10];
> sprintf(c, "%.2f", h);
> std::cout << c << std::endl;
>
> return the following output:
> 90.62

They do????? Declare/define/initialise 'd', then print 'h' and expect
something sensible? Come on...

I took your code, fixed it, put it in a write surrounding and got 90.63.
Try again, this time the right version:

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
double d = 90.625;
char c[10];
sprintf(c, "%.2f", d);
cout << c << endl;

return 0;
}

V