33

私のプログラムでは、通常、値をゼロで割ったときに無限大が発生します。ゼロをゼロで割ると不定になります。C++ で無限値と不定値をチェックするにはどうすればよいですか?

C++ では、無限大は 1.#INF で表されます。不確定は -1.#IND で表されます。問題は、変数が無限か不確定かをテストする方法です。無限のチェックは比較的簡単です。特定の C++ で無限の定義を見つけることができます。私の場合 (VS2003) では、std::numeric_limits::infinity() です。それを使用するには、「制限」を含める必要があります。この無限値を変数に代入し、その値をある値と比較して、その値が無限かどうかを確認できます。

不確定値を他の値と比較することはできないため、不確定は少し注意が必要です。どの比較も false を返します。このプロパティを使用して、それ自体と比較することで不確定値を検出できます。aVal という double 変数があるとします。通常、aVal != aVal は false を返します。ただし、値が不定の場合、aIndVal != aIndVal は true を返します。この奇妙な状況は、無限値には存在しません。つまり、aInfVal != aInfVal は常に false を返します。

不定値と無限値をチェックするために使用できる 2 つの関数を次に示します。

#include "limits.h"
#include "math.h"

bool isIndeterminate(const double pV)
{
    return (pV != pV);
} 

bool isInfinite(const double pV)
{
    return (fabs(pV) == std::numeric_limits::infinity())
}

これらのチェックのためのより良い方法はありますか?何か不足していますか?

4

6 に答える 6

19

Visual Studioの場合_isnan、 and _finite、またはおそらくを使用し_fpclassます。

ただし、C++11 対応の標準ライブラリとコンパイラにアクセスできる場合は、std::isnanandを使用できますstd::isinf

于 2009-01-04T11:45:34.980 に答える
3

これらを厳密な C++ のみのソリューションとして使用することもできます。型特性の使用によるセキュリティの追加と、おそらくis_inf.

template <bool> struct static_assert;
template <> struct static_assert<true> { };

template<typename T>
inline bool is_NaN(T const& x) {
    static_cast<void>(sizeof(static_assert<std::numeric_limits<T>::has_quiet_NaN>));
    return std::numeric_limits<T>::has_quiet_NaN and (x != x);
}

template <typename T>
inline bool is_inf(T const& x) {
    static_cast<void>(sizeof(static_assert<std::numeric_limits<T>::has_infinity>));
    return x == std::numeric_limits<T>::infinity() or x == -std::numeric_limits<T>::infinity();
}

(自作注意static_assert)

于 2009-01-04T22:08:37.263 に答える
3

厳密には C++03 の一部ではありませんが、コンパイラが標準の <math.h> ヘッダー ファイルの新しい C99 機能の一部を提供している場合、次の「関数のようなマクロ」にアクセスできる場合がisfiniteありisinfますisnan。もしそうなら、これらはこれらのチェックを実行するための最も簡単で安全な方法です.

于 2009-01-04T11:42:28.807 に答える
2

isfiniteC99またはPOSIXまたは私が思う何かからのものです。

それを行うハックな方法の 1 つは、テストすることx-x == 0です。xが無限または NaN の場合はx-xNaN なので比較は失敗し、x有限の場合x-xは で0あり、比較は成功します。ただし、を使用するisfiniteか、このテストを次のような関数/マクロにパッケージ化して、必要なisfiniteときにすべて削除できるようにすることをお勧めします。

于 2013-11-08T17:05:21.020 に答える