# difference between two doubles is wrong

This is a discussion on difference between two doubles is wrong within the C++ Programming forums, part of the General Programming Boards category; Hi guys, I'm new here. I'm trying to wrap my head around the precision issues when handling doubles. take a ...

1. ## difference between two doubles is wrong

Hi guys, I'm new here.
I'm trying to wrap my head around the precision issues when handling doubles.

take a look at the following code:

Code:
```int main()
{
double epsilon=0.001;
double d1=2.334;
double d2=2.335;

cout<<"epsilon is: "<<epsilon<<endl;
cout<<"d2-d1 is: "<<d2-d1<<endl;

if ((d2-d1)==epsilon)
cout<<"Equal!";
else
cout<<"Not equal!";
}```
the output for this code is:

Code:
```epsilon is: 0.001
d2-d1 is: 0.001
Not equal!```
what is going on here?

thanks for the help!

2. Never try to check two floatingpoint variables for equality

try this
Code:
```#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
double epsilon=0.001;
double d1=2.334;
double d2=2.335;

cout<<"epsilon is: "<< setprecision(20) << epsilon<<endl;
cout<<"d2-d1   is: "<< setprecision(20) << d2-d1 <<endl;

if ((d2-d1)==epsilon)
cout<<"Equal!";
else
cout<<"Not equal!";
}```
my output
Code:
```epsilon is: 0.0010000000000000000208
d2-d1   is: 0.00099999999999988986588
Not equal!```

Kurt

3. Classic. You should use an approximation error, like this
Code:
```If abs(x-y) < e
then equal```
Or as suggested here, use this
Code:
`if(fabs(d2-d1) <= epsilon * fabs(d2))`

4. as std10093 eluded to, floating point numbers are only approximate. they are limited by their precision and may have rounding errors.

5. thanks you both for the help!

Originally Posted by ZuK
my output
Code:
```epsilon is: 0.0010000000000000000208
d2-d1   is: 0.00099999999999988986588
Not equal!```

Kurt

that is so weird.
what went wrong here and why did setprecision() mess up the precision?

6. Originally Posted by Absurd
what went wrong here and why did setprecision() mess up the precision?
Nothing is messed up.
The value 0.001 is not a power of two and can only be approximated.
Kurt

7. Originally Posted by ZuK
Nothing is messed up.
The value 0.001 is not a power of two and can only be approximated.
Kurt
powers of two and integer multiples thereof can be perfectly represented. everything else is an approximation.

for example, 1.5 can be represented perfectly, because it is 3 * 2-1

however, 3.6 cannot be exactly represented, because it is not an integer multiple of a power of 2.

you can use this link to see what the actual binary representation of your floating point value will be.

8. what went wrong here and why did setprecision() mess up the precision?
O_o

1): There is nothing wrong, as explained, because the values may be approximations; the result of floating-point operations always depends on how the approximations are resolved even when the target values themselves have been subject to the same approximations.

2): The formatted streams do not print trailing fill by default; you need to use `std::fixed'.

Soma

Code:
```#include <iomanip>
#include <iostream>

const double kTarget(1.00048828125); // These values are subject to potentially greater errors
const double kEpsilon(0.00048828125); // thanks to multiple operations when not accurately represented.

double Update
(
const double fValue
, const unsigned int fMultiple
)
{
double sResult(fValue);
for(unsigned int cMultiple(1); fMultiple > cMultiple; ++cMultiple)
{
sResult += fValue;
}
//sResult *= 1.25; // You may alternate between values which can be
sResult *= 1.26;   // accurately represented and approximated values.
return(sResult);
}

int main()
{
using namespace std;
cout << fixed;
for(unsigned int cMultiple(0); 10 > cMultiple; ++cMultiple)
{
double sValue1(Update(kTarget, cMultiple));
double sDifference(Update(kEpsilon, cMultiple));
double sValue2(sValue1 + sDifference);
if((sValue2 - sValue1) != sDifference)
{
cout
<< setprecision(16) << sValue1 << " : "
<< setprecision(16) << sValue2 << " : "
<< setprecision(16) << sDifference << '\n'
;
}
}
return(0);
}```

9. Originally Posted by Elkvis
however, 3.6 cannot be exactly represented, because it is not an integer multiple of a power of 2.
This is not true.
It can be exactly represented, but not using 32-bit floating point. There just aren't enough bits in the mantissa. But given enough bits in the mantissa, any number can be represented.
Of course, machines only have limited storage available, which is why we have these truncation errors, as they are called.

10. OK, I tried it this way, that still does not work:

Code:
```#define EPSILON 0.001

double abs(double number)
{
return number>0 ? number : -number;
}

int main()
{
double d1(4.000);
double d2(4.001);
cout<<(abs(d1-d2)<=EPSILON);
}```
(I'm not using fabs() since we're not allowed to use any library other then iostream and sstream in our exercises)

will produce the output:
0

11. abs(4.000 - 4.001) yields 0.0010000000000003340 > 0.001.
Furthermore,
#define EPSILON 0.001
should be
const double Epsilon = 0.001;
Don't use #defines.

12. It can be exactly represented, but not using 32-bit floating point. There just aren't enough bits in the mantissa. But given enough bits in the mantissa, any number can be represented.
O_o

No. He is very definitely correct.

There are infinitely many numbers you can't represent with floating-point values because of the way they work with powers of two regardless of how many bits you have available in the mantissa.

Let's take an example: 0.49

Here we have a number less than one which tells us a lot. The multiplier (significand) has an implied one as the most significant digit. (This is part of the IEEE 754 standard.) We know we need a negative exponent to reduce our value below the implied minimum value which is reasonably at least one (1.mantissa * (2 ^ exponent)). We can see also that a -1 exponent will not be sufficient because 0.5 is also greater than our target value. Our exponent is obviously going to be -2 so we will need a value four times our target from the multiplier.

We now know need 0.96 in the mantissa (1.96 * (2 ^ -2)).

This is too small: (1/2^1)+(1/2^2)+(1/2^3)+(1/2^4) = 0.9375
This is too large: (1/2^1)+(1/2^2)+(1/2^3)+(1/2^4)+(1/2^5) = 0.96875

We need something between those value: (1/2^1)+(1/2^2)+(1/2^3)+(1/2^4)+(1/2^6) = 0.953125

Now we can begin to see where we will necessarily fail.

As we can see from the table, the number of base 10 digits in the mantissa corresponds with the negative power of two; in other words, the greater the negative power of two, the more base 10 digits you need to represent the value.

Code:
```1/2^1 = .5
1/2^2 = .25
1/2^3 = .125
1/2^64 = 0.0000000000000000000542101086242752217003726400434970855712890625```
We can see that nothing will ever get us to the .96 value we need. The least significant "...5" value will always be out of our reach to "correct" by adding something to it because any smaller power of two will have its own "...5" least significant digit.

The nearest we could possibly get, with a reduced exponent and a base 2 base, will always have a "...5" value in the least significant digit.

Soma

13. Originally Posted by Elysia
This is not true.
It can be exactly represented, but not using 32-bit floating point. There just aren't enough bits in the mantissa. But given enough bits in the mantissa, any number can be represented.
Of course, machines only have limited storage available, which is why we have these truncation errors, as they are called.
It would take an infinite number of bits to represent exactly; it's a repeating number in binary, the way that 1/6th is infinitely repeating in decimal.

14. Originally Posted by Cat
It would take an infinite number of bits to represent exactly; it's a repeating number in binary, the way that 1/6th is infinitely repeating in decimal.
I think it would still be impossible though since the cardinality of the set of real numbers is greater than the cardinality of the set of natural numbers (which applies to the number of bits you can have for a floating point representation).

Disclaimer: mathematics? Is that edible?

15. mathematics? Is that edible?
^_^

Is the square-root or cake muffin?

Soma

Page 1 of 2 12 Last