본문 바로가기
프로그래밍/C , C++

QNAN 과 IND 에 대해서

by 힝고니 2012. 8. 17.

프로그래밍을 하시다 보면 아무리 봐도 소스나 계산식에는 문제가 없는데 오동작을 하게 되는 경우가 있습니다.

저도 최근 그런 문제를 겪어 골머리를 썩혔는데요, 범인은 -1.#QNAN 이었습니다.

그럼 IND 와 QNAN 이란 무엇인가??

둘다 FPU 에서 이해할 수 없는 실수값을 처리할때 발생하는 문제 입니다.

IND 는 정의 되어있지 않은 숫자 , QNAN 은 값을 정할 수 없음, SNAN 은 유효하지 않은 값으로 

MSDN 에서도 확인하실 수 있습니다. ( NAN 은 Not a number )

그럼 앞에 붙는 -1.# 나 1.#는 무엇이냐면 1.# 는 양수 무한대, -1.#는 음수 무한대 입니다.

C 에서는 실수를 처리할때 지수부와 가수부를 나눠 저장하는데 지수부와 가수부의 사용 비트가 정해져 있기 때문에

정확하게 표현하지 못하는 실수가 있습니다. 특히 flot 의 경우 4바이트로 문제 발생이 많습니다.

( double 은 8바이트니 좀 낫죠 )

이런 문제로 flot 에서 사용하는 디파인을 보시면 FLT_EPSILON 나 FLT_MIN 등등이 있는데

FLT_MIN 의 경우 이보다 더 작은 값을 flot 에서 표시하려고 할때는 0으로 처리하게 됩니다.

0.0000000000000000000000000001 처럼 0은 아니지만 엄청나게 작은 값은 0으로 인식한다는 얘기가 되겠죠.

계산해서 나온 값이 단정도/배정도 포맷에 어긋나게 된다면 이런식으로 알 수 없는 값으로 처리가 됩니다.

오버플로우 되는 것이라고 보면 될거같네요.

이런 문제가 발생하는 경우 !!!

부동 소수점에서는 앞서 말씀드린것 처럼 0이 아닌 아주 작은수를 0으로 이해하는 경우기 았기에

a = b / c 와 같은 연산을 진행했을때 c 가 0.000000000000000000000000000000000000000001 이면

상식적으로는 0으로 나눈게 되겠지만 실제 0은 아니기에 연산은 진행되고 계산되어 나온 값은

이미 표현할 수 있는 값을 넘어버려 QNAN 등으로 처리되게 됩니다.

이럴 경우 값을 검사해줄 필요가 있는데요 flot 의 경우 

bool nan = (x <= FLT_MAX && x >= -FLT_MAX);

이런식으로 표현할 수 있는 최소, 최대값을 넘었는지 확인을 하여야 하겠습니다.

혹시 내용에 틀린 부분이나 부족한 점이 있다면 댓글 바랍니다 ^^