#### 20.8.6 Floating-Point Comparison Functions ¶

The standard C comparison operators provoke exceptions when one or other of the operands is NaN. For example,

    int v = a < 1.0;

will raise an exception if a is NaN. (This does not happen with `==` and `!=`; those merely return false and true, respectively, when NaN is examined.) Frequently this exception is undesirable. ISO C99 therefore defines comparison functions that do not raise exceptions when NaN is examined. All of the functions are implemented as macros which allow their arguments to be of any floating-point type. The macros are guaranteed to evaluate their arguments only once. TS 18661-1:2014 adds such a macro for an equality comparison that does raise an exception for a NaN argument; it also adds functions that provide a total ordering on all floating-point values, including NaNs, without raising any exceptions even for signaling NaNs.

Macro: `int` isgreater `(real-floating x, real-floating y)` ¶

  Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.

  This macro determines whether the argument x is greater than y. It is equivalent to `(x) > (y)`, but no exception is raised if x or y are NaN.

Macro: `int` isgreaterequal `(real-floating x, real-floating y)` ¶

  Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.

  This macro determines whether the argument x is greater than or equal to y. It is equivalent to `(x) >= (y)`, but no exception is raised if x or y are NaN.

Macro: `int` isless `(real-floating x, real-floating y)` ¶

  Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.

  This macro determines whether the argument x is less than y. It is equivalent to `(x) < (y)`, but no exception is raised if x or y are NaN.

Macro: `int` islessequal `(real-floating x, real-floating y)` ¶

  Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.

  This macro determines whether the argument x is less than or equal to y. It is equivalent to `(x) <= (y)`, but no exception is raised if x or y are NaN.

Macro: `int` islessgreater `(real-floating x, real-floating y)` ¶

  Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.

  This macro determines whether the argument x is less or greater than y. It is equivalent to `(x) < (y) || (x) > (y)` (although it only evaluates x and y once), but no exception is raised if x or y are NaN.

  This macro is not equivalent to `x != y`, because that expression is true if x or y are NaN.

Macro: `int` isunordered `(real-floating x, real-floating y)` ¶

  Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.

  This macro determines whether its arguments are unordered. In other words, it is true if x or y are NaN, and false otherwise.

Macro: `int` iseqsig `(real-floating x, real-floating y)` ¶

  Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.

  This macro determines whether its arguments are equal. It is equivalent to `(x) == (y)`, but it raises the invalid exception and sets `errno` to `EDOM` if either argument is a NaN.

Function: `int` totalorder `(const double *x, const double *y)` ¶
Function: `int` totalorderf `(const float *x, const float *y)` ¶
Function: `int` totalorderl `(const long double *x, const long double *y)` ¶
Function: `int` totalorderfN `(const _FloatN *x, const _FloatN *y)` ¶
Function: `int` totalorderfNx `(const _FloatNx *x, const _FloatNx *y)` ¶

  Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.

  These functions determine whether the total order relationship, defined in IEEE 754-2008, is true for `*x` and `*y`, returning nonzero if it is true and zero if it is false. No exceptions are raised even for signaling NaNs. The relationship is true if they are the same floating-point value (including sign for zero and NaNs, and payload for NaNs), or if `*x` comes before `*y` in the following order: negative quiet NaNs, in order of decreasing payload; negative signaling NaNs, in order of decreasing payload; negative infinity; finite numbers, in ascending order, with negative zero before positive zero; positive infinity; positive signaling NaNs, in order of increasing payload; positive quiet NaNs, in order of increasing payload.

Function: `int` totalordermag `(const double *x, const double *y)` ¶
Function: `int` totalordermagf `(const float *x, const float *y)` ¶
Function: `int` totalordermagl `(const long double *x, const long double *y)` ¶
Function: `int` totalordermagfN `(const _FloatN *x, const _FloatN *y)` ¶
Function: `int` totalordermagfNx `(const _FloatNx *x, const _FloatNx *y)` ¶

  Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.

  These functions determine whether the total order relationship, defined in IEEE 754-2008, is true for the absolute values of `*x` and `*y`, returning nonzero if it is true and zero if it is false. No exceptions are raised even for signaling NaNs.

Not all machines provide hardware support for these operations. On machines that don’t, the macros can be very slow. Therefore, you should not use these functions when NaN is not a concern.

NB: There are no macros `isequal` or `isunequal`. They are unnecessary, because the `==` and `!=` operators do not throw an exception if one or both of the operands are NaN.