In one of the C++ modules we have, we have an expression evaluation language.
\
EVDataElement NAME::eval( const EvalContext &ec, \
const bool recursiveFlag, \
EVEvaluatorTraceFormatter * trace ) \
{ \
/* EVTimer timer("(DECLARE_REL_EVAL)","eval","*", "", 1,1, 3); */ \
EVDataElement val ( \
(left->eval(ec, recursiveFlag, trace)) \
OP (right->eval(ec, recursiveFlag, trace)) ); \
return val; \
}
DECLARE_REL_EVAL(oLT,<)
DECLARE_REL_EVAL(oLE,<=)
DECLARE_REL_EVAL(oGT,>)
DECLARE_REL_EVAL(oGE,>=)
DECLARE_REL_EVAL(oEQ,==)
DECLARE_REL_EVAL(oNE,!=)
The module allows certain configuration rules to be set.
SO, if there was a rule in the database that said field1 – field2 > param1, it verifies this condition by passing to the expression language above and returns a result.
The problem we are facing now is say param1 = 3, and field1 = 6.15, and field2 = 3.15
It says the result is true. And I think it is because the difference of 6.15 and 3.15 results in 3.00
And when 3.00 is compared with 3, it thinks 3.00 is greater. Is there any way to work around this?
The reason I said we can’t use casting is because we never know what datatype might come through for left and right. I hope this question made sense.
You’re going to get the “usual conversions” when dealing with values of different primitive types. I don’t think there’s any way around this.
If you’re comparing
ints todoubles you’re going to need to come up with whatever rules you want to use when determining if two values are “close enough.” You may consider using thestd::modffunction (in<cmath>) in making the comparison.Consider:
Using Visual Studio 2010 on default settings (i.e., NOT using
fastmath) I get:3.0may be representable exactly in binary floating point math, but6.15 - 3.15isn’t3.0in binary floating point math.There have already been two references to the paper “What Every Computer Scientist Should Know About Floating-Point Arithmetic” which describes how binary floating point math works, and how it doesn’t always fit with human expectations. The main point to remember is that you hardly ever want to compare two floating point numbers for equality, especially if one (or both) of those numbers is the result of a math operation.
In your case, though, you’re trying to compare a
doublewith anint, and I have to assume you want some rounding. You might want to consider3.1to be equivalent to3. You might not. I really have no idea.If you were to use the rounding conventions taught in elementary school (round up on .5 or higher), you might do something like:
There are much more complex possibilities, including one described in the paper.