yohhoyの日記

技術的メモをしていきたい日記

浮動小数点数比較マクロ

C99で追加された浮動小数点数比較マクロについてメモ。同機能はC++11においても提供される。

比較マクロとそれに対応する比較演算の一覧。組込みの比較演算子では浮動小数点数例外(floating-point exception)が発生する可能性があるが、比較マクロでは決して浮動小数点数例外が発生しない。

マクロ 比較演算
isgreater(x,y) x > y
isgreaterequal(x,y) x >= y
isless(x,y) x < y
islessequal(x,y) x <= y
islessgreater(x,y) x < y || x > y
isunordered(x,y) 少なくとも一方がNaN

C99

JTC1/SC22/WG14 N1256 7.12.14より引用(下線部は強調)。

The relational and equality operators support the usual mathematical relationships between numeric values. 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.

#include <math.h>
int isgreater(real-floating x, real-floating y);
int isgreaterequal(real-floating x, real-floating y);
int isless(real-floating x, real-floating y);
int islessequal(real-floating x, real-floating y);
int islessgreater(real-floating x, real-floating y);
int isunordered(real-floating x, real-floating y);

C++11

C++11では同等機能を関数オーバーロードによって提供する。JTC1/SC22/WG21 N3337 26.8/p10より引用。

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:

bool isgreater(float x, float y);
bool isgreater(double x, double y);
bool isgreater(long double x, long double y);
// (snip)

関連URL