次のコードを検討してください。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
template<class T>
bool IsNaN(T t)
{
return t != t;
}
int main(int argc, char**argv)
{
double d1, d2;
sscanf(argv[1], "%f", &d1);
sscanf(argv[2], "%f", &d2);
double dRes = d1/d2;
cout << "dRes = " << dRes << "\n";
if(IsNaN(dRes))
cout << "Is NaN\n";
else
cout << "Not NaN\n";
}
いくつかの質問:
dRes = inf
。でも期待していたdRes = NaN
またはそのようなもの。Floating exception
。違いはなんですか?inf
と等しいかどうかを確認する方法は?scanf()
を使用する場合、double
は_%lf
_ではなく_%f
_を使用して読み取る必要があります。 _%f
_は入力を32ビットのfloat
に変換するため、変数の最初の32ビットは無効なデータで埋められ、最後の32ビットはガベージとして残されます。
はい。 _#include <limits>
_、 、[std::numeric_limits<double>::quiet_NaN()
。一部のコンパイラ(gccなど)では、 NAN
マクロを_<cmath>
_ で提供しています。
整数型にはNaNや無限大はありません。整数をゼロで除算すると、 例外(SIGFPE) が発生します。
_#include <cmath>
_、次に std::isinf(x)
。 std::isfinite(x)
を使用して、x
がNaNまたはInfinityでないことを確認します。
関数fpclassify
を使用すると、すべての特殊なケースの浮動小数点値を検査できます。
C99以降、<math.h>
はマクロとして、関数のファミリとして<cmath>
に、float
、double
、およびlong double
C++ 11以降、オーバーロードされた名前std::fpclassify
。
cppreferenceには いい例 があります