Hi all,

Here is a short summary of my piece of code.

double availableUnits       = calculateAvailableUnits(some arguments);
int    minimumRequiredUnits = getMinimumRequiredUnits(some arguments);

std::cout<<"minimumRequiredUnits = "<<minimumRequiredUnits<<std::endl; //prints 30
std::cout<<"availableUnits = "<<availableUnits<<std::endl; //prints 30

if (availableUnits < minimumRequiredUnits)
{
    //throw exception;
}
//rest of the code

Even though both variables have the value 30 in it, the if-condition gets satisfied and exception is thrown, which is wrong. I studied the problem a little more and found that the double variable availableUnits infact doesn't contain 30, instead it contains 29.9999. Is there any way I can get rid of this problem? Also, I cannot use ceil() as this would affect the functionality.

calculateAvailableUnits() function does some calculation which involves fractions, so the result 29.9999 instead of 30.

Maybe calculateAvailableUnits() need to round the return value to 2 or 3 decimal places so that it will return 30.00. The problem you are describing in the comparisons will most likely show its ugly head up in other places in your program too.

>>Even though both variables have the value 30 in it, the if-condition gets satisfied and exception is thrown

The int gets promoted and you are now doing a floating comparison. When doing floating comparison, as of right now you can do a simple range comparison :

//checks if lhs is equal to rhs given an epsilon
//that is returns true if lhs \in (rhs-epsilon,rhs+epsilon)
bool isEqual(const double lhs, const double rhs, const double epsilon = 0.0001){
  return lhs > rhs - epsilon && lhs < rhs + epsilon ;
}

Edited 5 Years Ago by firstPerson: n/a

Also, 30.000 can be represented exactly as a float, so I'm concerned that your calcualateAvailableUnits() function may be doing something which unnecessarily introduces error into your value. While fractions of units may be necessary in your computation, it may be worthwhile to consider if there's an intelligent way to keep your computations in integers. For example, if you need to track tenths of units (e.g. 3.1, 5.7), then manipulate your values in tenths of units (e.g. 31, 57) until you're finished, and then convert to floating-point units only at the end.

For what it's worth:
0.1 = 1/10 = 0*1/2 + 0*1/4 + 0*1/8 + 1*1/16 + 1*1/32 + 0*1/64 + 0*1/128 + 1*1/256 + 1*1/512 + ...
= 0.0001100110011001100... in binary.
Such a simple value (in decimal) cannot be completely/accurately represented in binary!

Thank you all,
@firstPerson : your suggestion looks sensible. will think of doing it.
I'll get back in case of any problems

This is precisely why many C++ guides advise against using the equality operator with floating point values, because it can give you headaches like this. firstPerson's solution is okay for most applications. float == 0.0 is one of the few values for which it will work 100% of the time.

This article has been dead for over six months. Start a new discussion instead.