C ++의 무한 및 불확실한 값을 어떻게 확인합니까?
-
03-07-2019 - |
문제
내 프로그램에서 인피니티는 일반적으로 값을 0으로 나눌 때 발생합니다. 0을 0으로 나눌 때 불확실합니다. C ++의 무한 및 불확실한 값을 어떻게 확인합니까?
C ++에서 인피니티는 1로 표시됩니다. 불확정은 -1.#ind로 표시됩니다. 문제는 변수가 무한대인지 불확실한 지 테스트하는 방법입니다. 무한대를 점검하는 것은 비교적 간단합니다. 특정 C ++에서 인피니티 정의를 찾을 수 있습니다. 내 경우 (vs2003), 그것은 std :: numeric_limits :: infinity ()입니다. 사용하려면 "한계"를 포함해야합니다. 이 무한 값을 변수에 할당 할 수 있으며 해당 값이 무한인지 확인하기 위해 일부 값과 비교할 수 있습니다.
불확실한 값을 다른 값과 비교할 수 없기 때문에 불확실한 것은 약간 까다 롭습니다. 모든 비교는 false를 반환합니다. 이 속성을 사용하여 자체를 비교하여 불확실한 값을 감지 할 수 있습니다. Aval이라는 이중 변수가 있다고 가정 해 봅시다. 정상적인 조건에서 aval! = aval은 false를 반환합니다. 그러나 값이 불확실한 경우 aindval! = aindval은 true를 반환합니다. 이 이상한 상황은 무한한 값, 즉 ainfval! = ainfval은 항상 거짓을 반환합니다.
다음은 불확실하고 무한한 값을 확인하는 데 사용할 수있는 두 가지 기능입니다.
#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
, 또는 아마도 _fpclass
.
그러나 C ++ 11 가능 표준 라이브러리 및 컴파일러에 액세스 할 수있는 경우 사용할 수 있습니다. std::isnan
그리고 std::isinf
.
다른 팁
C ++ 03은 C99를 제공하지 않지만 Isnan 그리고 ISINF 매크로, C ++ 11은 기능. 엄격한 C ++ 03 대신 C ++ 11을 사용할 수 있다면 매크로를 피함으로써 더 깨끗한 옵션이됩니다. 컴파일러 내장 및 플랫폼 의존적 기능.
C ++ 11 std::isfinite
보고 true
제외한 모든 값에 대해 inf
그리고 nan
; 그래서 !isfinite
한 번의 샷에서 무한하고 불확실한 값을 확인해야합니다.
C ++ 03의 일부는 아니지만 컴파일러가 표준의 새로운 C99 기능 중 일부를 제공하는 경우u003Cmath.h> 헤더 파일은 다음 "기능형 매크로"에 액세스 할 수 있습니다. isfinite
, isinf
, isnan
. 그렇다면이 확인을 수행하는 가장 쉽고 안전한 방법입니다.
이것을 엄격한 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
)
거기 있습니다 isfinite
C99 또는 Posix 또는 내가 생각하는 것.
그것을하는 한 가지 해킹 방법은 테스트하는 것입니다 x-x == 0
; 만약에 x
그렇다면 무한대 또는 Nan입니다 x-x
NAN이므로 비교가 실패하고 if x
그렇다면 유한합니다 x-x
~이다 0
그리고 비교는 성공합니다. 사용하는 것이 좋습니다 isfinite
, 그러나이 테스트가 다음과 같은 기능/매크로로 포장하십시오. isfinite
따라서 시간이 오면 모든 것을 제거 할 수 있습니다.
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