💡NaN의 특성과 sortedSetOf에서의 동작 방식

NaN다시 보기

기본적으로 NaN은 "숫자가 아님"을 나타내는 특별한 부동소수점 값입니다. 예를 들어 0을 0으로 나누거나, 음수의 제곱근을 구하는 등의 수학적으로 정의되지 않는 연산의 결과로 주로 발생합니다.

NaN의 가장 큰 특징은 자기 자신을 포함한 그 어떤 값과도 같지 않다는 것입니다.

이는 NaN이 특정 숫자를 나타내는 것이 아니라, "정의되지 않은 또는 표현할 수 없는 숫자"라는 상태를 의미하기 때문입니다. 따라서 두 개의 NaN 값이 있다고 해서 그 둘이 같은 "정의되지 않은 상태"라고 단정할 수 없습니다.

컬렉션(Collections)에서의 NaN

하지만 컬렉션, 특히 정렬된 컬렉션(예: TreeSet 또는 sortedSetOf를 통해 생성된 컬렉션)에서 NaN을 다룰 때는 동작 방식이 조금 다릅니다. 이는 IEEE 754 표준 부동소수점 산술 규칙과 JVM의 특정 구현 방식 때문입니다.

val set = sortedSetOf(Double.NaN, Double.NaN,Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY,0.0)
println(set) // [-Infinity, 0.0, Infinity, NaN]

1. sortedSetOf에서의 NaN 동작

위 코드의 sortedSetOf(Double.NaN, Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 0.0)를 실행했을 때, 결과는 [-Infinity, 0.0, Infinity, NaN]입니다.

여기서 주목할 점은 다음과 같습니다.

sortedSetOf는 요소를 자연적인 순서(natural ordering)에 따라 정렬합니다. Double 타입의 자연적 순서에서 NaN은 가장 큰 값으로 취급됩니다. 심지어 Double.POSITIVE_INFINITY (양의 무한대)보다도 더 큰 값으로 간주되어 정렬 순서상 가장 마지막에 위치하게 됩니다.

2. 컴파일러와 JVM의 역할