你如何检查 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
How do you check for infinite and indeterminate values in C++?
提问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 _isnan
and _finite
, or perhaps _fpclass
.
对于 Visual Studio,我会使用_isnan
and _finite
,或者也许_fpclass
.
But if you have access to a C++11-able standard library and compiler you could use std::isnan
and std::isinf
.
但是,如果您可以访问支持 C++11 的标准库和编译器,则可以使用std::isnan
和std::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 的isnan和isinf宏,但 C++11 通过将它们作为函数提供来将它们标准化。如果您可以使用 C++11,而不是严格的 C++03,那么通过避免宏、编译器内置函数和平台相关函数,这些将是更清晰的选择。
C++11's std::isfinite
returns true
for all values except inf
and nan
; so !isfinite
should check for infinite and indeterminate values in one shot.
C++11std::isfinite
返回true
除inf
and之外的所有值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 isfinite
from C99 or POSIX or something I think.
有isfinite
来自 C99 或 POSIX 或我认为的东西。
One hackish way to do it is to test x-x == 0
; if x
is infinite or NaN, then x-x
is NaN so the comparison fails, while if x
is finite, then x-x
is 0
and the comparison succeeds. I'd recommend using isfinite
, though, or packaging this test into a function/macro called something like isfinite
so you can get rid of it all when the time comes.
一种骇人听闻的方法是测试x-x == 0
;如果x
是无穷大或 NaN,则x-x
是 NaN,因此比较失败,而如果x
是有限的,则x-x
是0
,比较成功。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