Reputation: 13806
In the c++ standard for floating pointer number, there is std::isgreater
for greater comparison, and std::isless
for less comparison, so why is there not a std::isequal
for equality comparison? Is there a safe and accurate way to check if a double
variable is equal to the DBL_MAX
constants defined by the standard? The reason we try to do this is we are accessing data through service protocol, and it defines a double field when no data is available it will send DBL_MAX
, so in our client code when it's DBL_MAX
we need to skip it, and anything else we need to process it.
Upvotes: 4
Views: 612
Reputation: 52294
The interest of isgreater
, isless
, isgreaterequal
, islessequal
compared to >
, <
, >=
and <=
is that they do not raise FE_INVALID (a floating point exception, these are different beasts than C++ exceptions and are not mapped to C++ exceptions) when comparing with a NaN while the operators do.
As ==
do not raise a FP exception, there is no need of an additional functionality which does.
Note that there is also islessgreater
and isunordered
.
If you are not considering NaN or not testing the floating point exception there is no need to worry about these functions.
Considering equality comparison ==
is what to use if you want to check that the values are the same (ignoring the issues related to signed 0 and NaN). Depending on how you are reaching these values, it is sometimes useful to consider an approximate equality comparison -- but using one systematically is not recommended, for instance such approximate equality is probably not transitive.
In your context of a network protocol, you have to consider how the data is serialized. If the serialization is defined as binary, you can probably reconstruct the exact value and thus ==
is what you want so compare against DBL_MAX
(for other values, check what is specified for signed 0 and NaN an know that there are signalling and quiet NaN are represented by different bit patterns although IEEE 754-2008 recommend now one of them). If the representation is decimal, you'll have to check if the representation is precise enough for the DBL_MAX
value be reconstructable (and pay attention to rounding modes).
Note that I'd have considered a NaN for representing the no data available case instead of using a potentially valid value.
Upvotes: 6
Reputation: 26302
Is there a safe and accurate way to check if a double variable is equal to the
DBL_MAX
constants defined by the standard?
When you obtain a floating point number as a result of evaluating some expression, then ==
comparison doesn't make sense in most cases due to finite precision and rounding errors. However, if you first set a floating point variable to some value, then you can compare it to that value using ==
(with some exceptions like positive and negative zeros).
For example:
double v = std::numeric_limits<double>::max();
{ conditional assignment to v of a non-double-max value }
if (v != std::numeric_limits<double>::max())
process(v);
std::numeric_limits<double>::max()
is exactly representable as double
(it is double
), so this comparison should be safe and should never yield true
unless v
was reassigned.
Upvotes: 0
Reputation: 3495
Equal function between to floating point have no sense, because the floating point numbers have rounding.
So if you want compare 2 floating point numbers for equality the best way is to declare a significant epsilon(error) for your comparison and then verify that the first number is in around the second.
To do this you can verify if first number is greater than second number minus epsilon and the first number is lower than the second number plus epsilon. Ex.
if ( first > second - epsilon && first < second + epsilon ){
//The numbers are equal
}else{
//The numbers are not equal
}
Upvotes: -4