<aside> 💡 IEEE 754, 부동소수점의 저장 방식을 아신다면 더 쉽게 읽을 수 있습니다.
</aside>
isnan
, isinf
isnan
은 인자가 NaN
일 때, isinf
는 인자가 infinity
나 -infinity
일 때 참을 반환합니다.
NaN
, infinity
NaN
은 not a number의 약자로, 숫자가 아닌 비정상적인 값을 나타냅니다.
infinity
는 무한히 큰 값을 나타내는데, 무한히 작은 값을 나타내는 -infinity
도 있습니다.
지수부 비트가 모두 켜져 있으며 가수부 비트가 모두 꺼져 있다면 infinity
(또는 -ininity
),
그리고 지수부 비트가 모두 켜져 있으며 가수부 비트 중 하나라도 켜져 있다면 NaN
입니다.
비트연산을 사용한 isnan
구현 예시, long double
에 대해서는 불가능
그 점을 이용하면 지수부 비트와 가수부 비트로 isnan
, isinf
를 구현할 수 있습니다.
단, float
과 double
에 대해서요. long double
에 대해서는 구현할 수 없습니다.
long double
은 안 될까?이유는 간단합니다. 지수부와 가수부가 어디까지인지 알 수 없기 때문입니다.
long double
의 크기는 80비트일 수도, 128비트일 수도, 둘 다 아닐 수도 있습니다.
long double
의 크기는 sizeof
로 알아낼 수 있지만, 어디까지가 지수부일지는 글쎄요…
NaN
과 infinity
의 특성을 활용한 구현NaN
은 무엇과 비교해도 같지 않습니다. 심지어 NaN == NaN
조차 false
입니다.
infinity
와 -infinity
는 0이나 infinity를 제외하고 무엇을 곱해도 부호만 바뀝니다.
즉 f
는, f != f
이면 NaN
이고, f * 2 == f
이면 0
, infinity
, -infinity
중 하나입니다.
bool isnan_float(float f)
{
return (f != f);
}
bool isinf_float(float f)
{
return (f != 0 && f * 2 == f);
}
이 방법 외에도, isinf(f)
인 경우 isnan(f - f)
도 성립하므로, 이 특성을 활용해도 됩니다.