33

在我的程序中,当一个值被零除时,通常会出现无穷大。当我将零除以零时,我变得不确定。如何在 C++ 中检查无限和不确定的值?

在 C++ 中,无穷大由 1.#INF 表示。不确定由 -1.#IND 表示。问题是如何测试一个变量是无限的还是不确定的。检查无穷大相对简单:您可以在特定的 C++ 中找到无穷大定义。对于我的情况(VS2003),它是 std::numeric_limits::infinity()。您必须包含“限制”才能使用它。您可以将此无限值分配给变量,然后将其与某个值进行比较,以检查该值是否为无限。

Indeterminate 有点棘手,因为您无法将不确定的值与其他值进行比较。任何比较都返回 false。您可以使用此属性通过将其与自身进行比较来检测不确定的值。假设您有一个名为 aVal 的双变量。在正常情况下,aVal != aVal 返回 false。但如果值不确定,aIndVal != aIndVal 返回真。无限值不存在这种奇怪的情况,即 aInfVal != aInfVal 总是返回 false。

以下是两个可用于检查不确定值和无限值的函数:

#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,我会使用_isnanand_finite或者_fpclass.

但是,如果您可以访问支持 C++11 的标准库和编译器,则可以使用std::isnanstd::isinf.

于 2009-01-04T11:45:34.980 回答
10

虽然 C++03 没有提供 C99 的isnanisinf ,但 C++11 将它们标准化为函数。如果您可以使用 C++11,而不是严格的 C++03,那么这些将是更简洁的选择,避免使用宏、编译器内置函数和依赖于平台的函数。

C++11对除and之外的所有值的std::isfinite返回;所以应该一次检查无限和不确定的值。trueinfnan!isfinite

于 2013-07-18T12:50:11.377 回答
3

虽然不是严格意义上的 C++03 的一部分,但如果您的编译器提供标准 <math.h> 头文件的一些新 C99 功能,那么您可以访问以下“类似函数的宏”:isfiniteisinfisnan。如果是这样,这些将是执行这些检查的最简单和最安全的方法。

于 2009-01-04T11:42:28.807 回答
3

您也可以将它们用作严格的仅限 C++ 的解决方案。除了通过使用类型特征来增加安全性之外,它们并没有真正提供比 OP 的解决方案更多的东西,而且在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 回答
2

isfinite来自 C99 或 POSIX 或我认为的东西。

一种骇人听闻的方法是测试x-x == 0;如果x是无限或NaN,那么x-x是NaN,所以比较失败,而如果x是有限的,那么x-x0并且比较成功。不过,我建议使用isfinite,或者将此测试打包到一个函数/宏中,称为类似的东西,isfinite以便您可以在时机成熟时摆脱它。

于 2013-11-08T17:05:21.020 回答
0
if (x!=x)              ... then x is nan
if (x>0 && x/x != x/x) ... then x is +inf
if (x<0 && x/x != x/x) ... then x is -inf

这也可能有效(但涉及调用 exp() 和测试双打的相等性):

if (exp(-x)==0.) ... then x is inf
if (exp(x)==0.)  ... then x is -inf
于 2013-11-08T16:45:12.937 回答