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

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

Indeterminate有点棘手,因为你无法将不确定的值与其他值进行比较。任何比较都返回false。您可以使用此属性通过将其与自身进行比较来检测不确定值。假设您有一个名为aVal的双变量。在正常情况下,aVal!= aVal返回false。但是如果值是不确定的,则aIndVal!= aIndVal返回true。对于无限值,这种奇怪的情况不存在,即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())
}

这些检查是否有更好的方法,我错过了什么?

有帮助吗?

解决方案

对于Visual Studio,我会使用 _isnan _finite ,或者< a href =“http://msdn.microsoft.com/en-us/library/aa246882(VS.60).aspx”rel =“noreferrer”> _fpclass

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

其他提示

虽然C ++ 03没有提供C99的 isnan isinf ,C ++ 11标准化将它们作为功能提供。如果您可以使用C ++ 11而不是严格的C ++ 03,那么通过避免使用宏,这些将是更清晰的选择,编译器内置函数和与平台相关的函数。

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

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

您也可以将它们用作严格的C ++解决方案。除了通过使用类型特征增加安全性以及在is_inf情况下最小的速度提升时,它们实际上提供的不仅仅是OP的解决方案。

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

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

这样做的一个hackish方法是测试x-x == 0;如果x是无限或NaN,则x-x是NaN,因此比较失败,而如果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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top