質問にあるように、私はMIPSPRo Cコンパイラを使用しており、分子と分母の両方がゼロである一部のデータセットに対してNaNを返す操作があります。これを防ぐにはどうすればよいですか?
4 に答える
if句を使用しますか?また、なぜこの数学的不可能性を無視したいのか興味があります。この場合、入力が間違っていない/無意味ではないことを確認しますか?
MIPSProコンパイラを使用するSGIシステムでは、の機能を使用して、さまざまな浮動小数点例外の処理を非常に正確に設定できますsigfpe.h
。たまたま、ゼロによるゼロ除算はそのようなケースの1つです。
#include <stdio.h>
#include <sigfpe.h>
int main (void) {
float x = 0.0f;
(void) printf("default %f / %f = %f\n", x, x, (x / x));
invalidop_results_[_ZERO_DIV_ZERO] = _ZERO;
handle_sigfpes(_ON, _EN_INVALID, 0, 0, 0);
(void) printf("handled %f / %f = %f\n", x, x, (x / x));
return 0;
}
使用中で:
arkku@seven:~/test$ cc -version
MIPSpro Compilers: Version 7.3.1.3m
arkku@seven:~/test$ cc -o sigfpe sigfpe.c -lfpe
arkku@seven:~/test$ ./sigfpe
default 0.000000 / 0.000000 = nan0x7ffffe00
handled 0.000000 / 0.000000 = 0.000000
ご覧のとおり、結果を設定する_ZERO_DIV_ZERO
と、同じ除算の結果が変わります。同様に、ゼロによる通常の除算を処理できます(たとえば、結果として無限大が必要ない場合)。
もちろん、これはどれも標準ではありません。各除算の後にNaNをチェックする方が移植性が高く、前にゼロをチェックする方がさらに優れています。C99は、の浮動小数点環境をある程度制御fenv.h
できますが、これに適したものはないと思います。いずれにせよ、私の古いMIPSProはC99をサポートしていません。
小さなエラーを導入してもかまわない場合は、浮動小数点演算を実行していると仮定して、分母に小さな値を追加できます。どうやらいくつかの小さな値が定義されています:
DBL_MINは最小のdoubleです
DBL_EPSILONは最小のdoublestx + DBL_EPSILON!= x
だから私は試してみます
#include <float.h>
#define EPS DBL_MIN
double divModified(double num, double denom) {
return num / (denom + EPS);
}
IEEE 754(浮動小数点の仕様)では、0.0/0.0は数値ではないとされていNaN
ます。それ以外のものにしたい場合は、if
句内のオペランドが両方ともゼロであるかどうかを検出し、指定したい値を返すのが最善の方法です。おそらくこのように:
#define WonkyDiv(a,b) ((a)==0.0&&(b)==0.0 ? 0.0 : (a)/(b))
float wonkyResult = WonkyDiv(numerator, denominator);