你如何检查 C++ 中的无限和不确定值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/410853/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:12:33  来源:igfitidea点击:

How do you check for infinite and indeterminate values in C++?

c++visual-c++floating-pointnaninfinity

提问by Samil

In my programs infinity usually arises when a value is divided by zero. I get indeterminate when I divide zero by zero. How do you check for infinite and indeterminate values in C++?

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

In C++, infinity is represented by 1.#INF. Indeterminate is represented by -1.#IND. The problem is how to test if a variable is infinite or indeterminate. Checking infinity is relatively straightforward: You find the infinity definition in your particular C++. For my case (VS2003), it is std::numeric_limits::infinity(). You have to include "limits" in order to use it. You can assign this infinite value to a variable and you can compare it to some value in order to check if that value is infinite.

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

Indeterminate is a little tricky, because you cannot compare an indeterminate value to some other value. Any comparison returns false. You can use this property to detect an indeterminate value by comparing it to itself. Let's say you have a double variable called aVal. Under normal conditions, aVal != aVal returns false. But if the value is indeterminate, aIndVal != aIndVal returns true. This weird situation is not present for infinite values, i.e. aInfVal != aInfVal always returns false.

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

Here are two functions that can be used to check for indeterminate and infinite values:

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

#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())
}

Are there better ways for these checks, am I missing anything?

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

采纳答案by dalle

For Visual Studio I would use _isnanand _finite, or perhaps _fpclass.

对于 Visual Studio,我会使用_isnanand _finite,或者也许_fpclass.

But if you have access to a C++11-able standard library and compiler you could use std::isnanand std::isinf.

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

回答by legends2k

Although C++03 doesn't provide C99's isnanand isinfmacros, C++11 standardizes them by providing them as functions. If you can use C++11, instead of strict C++03, then these would be cleaner options, by avoiding macros, compiler built-insand platform-dependant functions.

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

C++11's std::isfinitereturns truefor all values except infand nan; so !isfiniteshould check for infinite and indeterminate values in one shot.

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

回答by Konrad Rudolph

You may also use these as a strict C++-only solution. They don't really offer more than the OP's solution except added security through use of type traits and perhaps the tiniest speed boost in the case of is_inf.

您也可以将它们用作严格的仅限 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();
}

(beware of self-made static_assert)

(小心自制static_assert

回答by CB Bailey

Although not strictly a part of C++03, if your compiler provides some of the new C99 features of the standard <math.h> header file, then you may have access to the following "function-like macros": isfinite, isinf, isnan. If so, these would be the easiest and safest way to perform these checks.

尽管严格来说不是 C++03 的一部分,但如果您的编译器提供了标准 <math.h> 头文件的一些新的 C99 特性,那么您可能可以访问以下“类似函数的宏”:isfinite, isinf, isnan. 如果是这样,这些将是执行这些检查的最简单和最安全的方法。

回答by tmyklebu

There's isfinitefrom C99 or POSIX or something I think.

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

One hackish way to do it is to test x-x == 0; if xis infinite or NaN, then x-xis NaN so the comparison fails, while if xis finite, then x-xis 0and the comparison succeeds. I'd recommend using isfinite, though, or packaging this test into a function/macro called something like isfiniteso you can get rid of it all when the time comes.

一种骇人听闻的方法是测试x-x == 0;如果x是无穷大或 NaN,则x-x是 NaN,因此比较失败,而如果x是有限的,则x-x0,比较成功。isfinite不过,我建议使用,或将此测试打包到一个名为 like 的函数/宏中,isfinite这样您就可以在时机成熟时将其全部删除。

回答by Azrael

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

this might also work (but involves call to exp() and testing equality of doubles):

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

if (exp(-x)==0.) ... then x is inf
if (exp(x)==0.)  ... then x is -inf