1==1 is false???

Hi there
I have the following code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
using namespace std;

int main(){
	double price=1;
	double added=0;
	int input;
	cin >> input;
	while(input!=0){
		if(input==1){
			added+=0.25;
		}
		else if(input==2){
			added+=0.10;
		}
		else if(input==3){
			added+=0.05;
		}
		else if(input==4){
			added+=0.01;
		}
		cin >> input;
	}
	if(added==price){
		cout << "Here you go!" << endl;
	}
	else if(added<price){
		cout << "Insufficient funds! (" << added << ")" << endl;
	}
	else if(added>price){
		cout << "Here you go! Your change is " << added-price << endl;
	}
	cout << added << " " << price;
}


it takes input from the user until he enters a zero. 1 adds 0.25 to what he has previously entered, 2 adds 0.10 and so on. Then after entering the zero the program compares the added input to the variable "price" (which is 1 by default).

The problem with this is, when I e.g. enter:
"1 1 2 2 2 2 2" added is set to 1, but the comparison between added and price fails (it is set to false) and it prints out "Insufficient funds!" as though added was smaller than price.

The same happens when I enter:
"1 1 1 3 3 3 3 3" which is also 1. In this case though it prints out "Here you go! Your change is..." as though added was bigger than price.

What did I do wrong? :S
greetings
I'm not sure if I understand what you're trying to do, but it might help you to output added, price and input at different stages, so you can see exactly what's going on.
The thing is with both of those examples I print out price and added and both say exactly 1 so I don't get why they wouldn't compare -.-
Looks like a floating point rounding error to me.
http://floating-point-gui.de/errors/comparison/
There is a big problem comparing floats, they use binary representation and not all number can be represented exactly. The number 0.1 is one of these so this won't work:

1
2
3
4
double a = 0.1;

if (1.0 == 10.0 * a)   //guaranted to fail


Float point is like this:

FloatValue = Desired value plus or minus very small amount.

Google floating point and DBL_EPSILON to find out how to do it.

HTH

Edit: Ninja'd
Last edited on
I still don't quite get what I'm supposed to do to avoid this mistake :S I mean, I could just multiply all the numbers by hundred of course, but I don't understand what this DBL_EPSILON thing is ^^
You could include the math header and do something like this. It's not perfect, but it'll probably suit your needs.

1
2
3
4
5
// Replace
if(added==price)

// With
if (fabs(price - added) < 0.00001)
EPSILON is the smallest biggest number such that 1 + EPSILON still equals 1. There is a FLT_EPSILON for floats and DBL_EPSILON for doubles. The EPSILON's need to be scaled according to the number you have. If your number is 1000 say, then you need 1000 * DBL_EPSILON.

The thing to understand is the 'distance' between representable numbers over different ranges. If we consider a float that equals 1, the next greatest number that can represented is about 1 + 1E-8, so the 'distance' is 1E-8. If the float is 1E8, the next greater number is 1.0000001E8, so the distance is 1.0. At 1E9 the distance is 10, at 1E10 distance is 100. So when testing for equality you really need to test that your number is between the number below and the number above. That's where the EPSILON's come in. Similar for for less than and greater than.

The reason that inexact representation occurs, is because of the binary fractions that are used. A binary fraction of 1.1101 is 1 + 0.5 + 0.25 + 0.0625. USing this method it is possible to represent most of the numbers, but not all.

The other consideration is the precision of the answer that you require. Say you wish to use a prcision of 0.01, you can do this:

1
2
3
4
5
6
7
8
double MyPrecision = 0.01;
double MyDouble = 0.1;  //not exact is about 0.0999...97 to 16 sig figures 
double MyNum = 10 * MyDouble ;  // not exact 0.999...97

if (MyNum  > (1.0 - MyPrecision)  && MyNum  < 1.0 +MyPrecision )  //this is true
            cout << "MyNum equals 1.0   0.01 precision" << endl;
else 
            cout << "MyNum is not equal to 1.0   0.01 precision" << endl;


This is OK but the 0.01 suffers from the same problem as other floating point numbers, so in some situations you might still need to use DBL_EPSILON as well.

Generally floating point is a pain in the A**, but you can get used to it.

Google some more there is heaps of stuff about this topic.

HTH Hope this helps
Last edited on
Thanks I think I get it now. Still did it with integers multiplied by 100 though now :D (that seemed like the easiest way to me)
iHutch105's solution is a good one (pretty simple) & gets around the confusion of * by 100.
Topic archived. No new replies allowed.