ObjecTips

Swift & Objective-C で iOS とか macOS とか

float 等の浮動小数点数の誤差を考慮して等価比較する

よく定数を忘れるので備忘

float の誤差を考慮して等価比較するには FLT_EPSILON を使う
double のための DBL_EPSILON
long double のための LDBL_EPSILON
も用意されている。

例えば float afloat b とイコールであるかをチェックするには a と b との差が FLT_EPSILON の値以下かどうか、つまり差の絶対値を FLT_EPSILON と比較演算する。

これが

float a;
float b;
// 何らかの処理

if (a == b) {
}

こうなる ↓

float a;
float b;
// 何らかの処理

if (fabsf(a - b) < FLT_EPSILON) {
}

double の場合は ↓

double a;
double b;
// 何らかの処理

if (fabs(a - b) < DBL_EPSILON) {
}

long double の場合は ↓

long double a;
long double b;
// 何らかの処理

if (fabsl(a - b) < LDBL_EPSILON) {
}

となる。

EPSILON の定数は float.h に

#define FLT_EPSILON __FLT_EPSILON__
#define DBL_EPSILON __DBL_EPSILON__
#define LDBL_EPSILON __LDBL_EPSILON__

abs 関数は math.h に定義されている。

extern float fabsf(float);
extern double fabs(double);
extern long double fabsl(long double);

EPSILON というワードを忘れた時は FLT_MAXFLT_MIN を経由して float.h を探す事にしよう。
もしくはイプシロンイプシロン...と頭に刻み込む。