IT story

C에서 nan과 inf를 사용하는 방법?

hot-time 2020. 9. 18. 19:26
반응형

C에서 nan과 inf를 사용하는 방법?


오류가있는 경우 nan 또는 inf를 반환 할 수있는 숫자 메서드가 있으며 테스트 목적으로 상황이 올바르게 처리되고 있는지 확인하기 위해 일시적으로 nan 또는 inf를 반환하도록 강제하고 싶습니다. C에서 nan 및 inf 값을 생성 하는 신뢰할 수 있고 컴파일러 독립적 인 방법이 있습니까?

약 10 분 동안 인터넷 검색을 한 후 컴파일러 종속 솔루션 만 찾을 수있었습니다.


구현에 다음이 있는지 테스트 할 수 있습니다.

#include <math.h>
#ifdef NAN
/* NAN is supported */
#endif
#ifdef INFINITY
/* INFINITY is supported */
#endif

의 존재는 INFINITYC99 (또는 적어도 최신 초안)에 의해 보장되며 "사용 가능한 경우 양수 또는 부호없는 무한대를 나타내는 float 유형의 상수 표현식으로 확장됩니다. 그렇지 않으면 번역 시간에 오버플로되는 float 유형의 양수 상수로 확장됩니다."

NAN 정의 될 수도 있고 정의되지 않을 수도 있습니다. "구현이 float 유형에 대해 조용한 NaN을 지원하는 경우에만 정의됩니다. 이는 조용한 NaN을 나타내는 float 유형의 상수 표현식으로 확장됩니다."

부동 소수점 값을 비교하는 경우 다음을 수행하십시오.

a = NAN;

그렇다하더라도,

a == NAN;

거짓입니다. NaN을 확인하는 한 가지 방법은 다음과 같습니다.

#include <math.h>
if (isnan(a)) { ... }

다음 a != a수행 할 수도 있습니다 a. NaN 인지 테스트합니다 .

도있다 isfinite(), isinf(), isnormal(), 및 signbit()매크로에 math.hC99한다.

C99에는 다음과 같은 nan기능 도 있습니다 .

#include <math.h>
double nan(const char *tagp);
float nanf(const char *tagp);
long double nanl(const char *tagp);

(참조 : n1256).

문서 INFINITY 문서 NAN


C (또는 C ++) 표준이 부동 소수점 수학 유형이 NAN 또는 INF를 지원해야한다고 말하지 않기 때문에이를 수행하는 컴파일러 독립적 인 방법은 없습니다.

편집 : 방금 C ++ 표준의 문구를 확인했는데 다음과 같은 함수 (템플릿 클래스 numeric_limits의 구성원)가 표시됩니다.

quiet_NaN() 
signalling_NaN()

"사용 가능한 경우"NAN 표현을 반환합니다. "사용 가능한 경우"가 의미하는 바를 확장하지 않지만 "구현의 FP 담당자가 지원하는 경우"와 같은 것으로 추정됩니다. 마찬가지로 기능이 있습니다.

infinity() 

"사용 가능한 경우"양의 INF 담당자를 반환합니다.

이것들은 모두 <limits>헤더에 정의되어 있습니다. C 표준에도 비슷한 것이 있다고 생각하지만 (아마도 "사용 가능한 경우") 현재 C99 표준의 사본이 없습니다.


컴파일러 독립적 인 방법이지만 프로세서 독립적 인 방법은 아닙니다.

int inf = 0x7F800000;
return *(float*)&inf;

int nan = 0x7F800001;
return *(float*)&nan;

이것은 IEEE 754 부동 소수점 형식을 사용하는 모든 프로세서에서 작동합니다 (x86이 수행함).

UPDATE: Tested and updated.


This works for both float and double:

double NAN = 0.0/0.0;
double POS_INF = 1.0 /0.0;
double NEG_INF = -1.0/0.0;

Edit: As someone already said, the old IEEE standard said that such values should raise traps. But the new compilers almost always switch the traps off and return the given values because trapping interferes with error handling.


double a_nan = strtod("NaN", NULL);
double a_inf = strtod("Inf", NULL);

<inf.h>

/* IEEE positive infinity.  */

#if __GNUC_PREREQ(3,3)
# define INFINITY   (__builtin_inff())
#else
# define INFINITY   HUGE_VALF
#endif

and

<bits/nan.h>
#ifndef _MATH_H
# error "Never use <bits/nan.h> directly; include <math.h> instead."
#endif


/* IEEE Not A Number.  */

#if __GNUC_PREREQ(3,3)

# define NAN    (__builtin_nanf (""))

#elif defined __GNUC__

# define NAN \
  (__extension__                                  \
   ((union { unsigned __l __attribute__ ((__mode__ (__SI__))); float __d; })  \
    { __l: 0x7fc00000UL }).__d)

#else

# include <endian.h>

# if __BYTE_ORDER == __BIG_ENDIAN
#  define __nan_bytes       { 0x7f, 0xc0, 0, 0 }
# endif
# if __BYTE_ORDER == __LITTLE_ENDIAN
#  define __nan_bytes       { 0, 0, 0xc0, 0x7f }
# endif

static union { unsigned char __c[4]; float __d; } __nan_union
    __attribute_used__ = { __nan_bytes };
# define NAN    (__nan_union.__d)

#endif  /* GCC.  */

I'm also surprised these aren't compile time constants. But I suppose you could create these values easily enough by simply executing an instruction that returns such an invalid result. Dividing by 0, log of 0, tan of 90, that kinda thing.


I usually use

#define INFINITY (1e999)

or

const double INFINITY = 1e999

which works at least in IEEE 754 contexts because the highest representable double value is roughly 1e308. 1e309 would work just as well, as would 1e99999, but three nines is sufficient and memorable. Since this is either a double literal (in the #define case) or an actual Inf value, it will remain infinite even if you're using 128-bit (“long double”) floats.

참고URL : https://stackoverflow.com/questions/1923837/how-to-use-nan-and-inf-in-c

반응형

'IT story' 카테고리의 다른 글

Sqlite 또는 MySql?  (0) 2020.09.18
[:]은 무슨 뜻인가요?  (0) 2020.09.18
UIView의 경계를 넘어서는 상호 작용  (0) 2020.09.18
자바에서 추상화 대 캡슐화  (0) 2020.09.18
foreach와 each의 D3 javascript 차이점  (0) 2020.09.18