In the latest C++ standard, I noticed the following macros :
bool isgreater(float x, float y); bool isgreaterequal(float x, float y); bool isless(float x, float y); bool islessequal(float x, float y); bool islessgreater(float x, float y); bool isunordered(float x, float y);
These macros are from C (7.12.14 and 7.12.14).
So, why would someone use these macros, instead of operators? Is there anything special that these macros are doing (like checking for inf
), or are they the same as their corresponding operator?
C++ example :
#include <iostream> #include <cmath> int main() { float x=0.2; float y=0.5; std::cout << x << " < " << y << " : " << std::boolalpha << std::islessequal( x, y ) << std::endl; std::cout << x << " < " << y << " : " << std::boolalpha << ( x <= y ) << std::endl; }
Floating point comparison in C++To compare two floating point values, we have to consider the precision in to the comparison. For example, if two numbers are 3.1428 and 3.1415, then they are same up to the precision 0.01, but after that, like 0.001 they are not same.
Description. It is very usual for the C programming language beginners to compare a floating point number using the "==" operator. Floating point numbers must not be compared with the "==" operator.
Float is used mostly in graphic libraries because of their extremely high demand for processing power. Because the range is smaller than in the double type, float has been the better choice when dealing with thousands or millions of floating-point numbers because of its speed.
The values used in an expression are considered as double (double precision floating point format) unless a 'f' is specified at the end. So the expression “x==0.1” has a double on right side and float which are stored in a single precision floating point format on left side.
Unlike the relational operators, these macros do really only return a boolean value and do never raise any floating point exception.
In short: You only have to deal with true
/false
and nothing else.
references:
The Open Group descriptions (not the C or C++ standard, but highly relevant in the Unix/Linux world and almost always similar to the standards):
C++ standard:
C Library [c.math]:
The classification/comparison functions behave the same as the C macros with the corresponding names defined in 7.12.3, Classification macros, and 7.12.14, Comparison macros in the C Standard. Each function is overloaded for the three floating-point types, as follows [...]
C standard:
7.12.14 Comparison macros
[...] For any ordered pair of numeric values exactly one of the relationships — less, greater, and equal — is true. Relational operators may raise the ‘‘invalid’’ floating-point exception when argument values are NaNs. For a NaN and a numeric value, or for two NaNs, just the unordered relationship is true. The following subclauses provide macros that are quiet (non floating-point exception raising) versions of the relational operators, and other comparison macros that facilitate writing efficient code that accounts for NaNs without suffering the ‘‘invalid’’ floating-point exception. In the synopses in this subclause, real-floating indicates that the argument shall be an expression of real floating type.
isgreater
et al. were incorporated into C++11 from C99. They are defined to not raise the invalid floating-point exception when x
and/or y
are signalling NaN
values.
The rationale given is:
This macro is a quiet (non-floating-point exception raising) version of a relational operator. It facilitates writing efficient code that accounts for NaNs without suffering the invalid floating-point exception.
The numeric value of the macro on NaN
is the same as always; NaN
values compare false to all other values including NaN
values under all relational operators and the new macros.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With