NaN 이란?

아래 코드에서 num의 값을 출력했을 때, 결과는 NaN이 나오게 된다.

double x = 0.0;
double y = 0.0;
double num = x/y;
System.out.println(num); // NaN 출력

NaN이란, Not A Number의 줄임말로, 정상적인 숫자가 아니라는 것을 의미한다.
마이너스 값에 대하여 제곱근을 하거나, 숫자를 0으로 나누는 등의 경우와 같이 수학적으로 연산이 불가하지만, 억지로 연산했을 때 마주하게 된다.

이러한 경우 더 이상의 연산이 불가하기 때문에, 이를 NaN인지 아닌지를 체크해줘야 한다.
기본적으로 JAVA에서 NaN 관련된 메소드는 아래 두 가지가 있다.

1. Double.NaN

System.out.println(num == Double.NaN);

false

System.out.println(num.equals(Double.NaN));

true

위와 같이 NaN 메소드는 결과가 지맘대로다.
그래서 NaN값을 확인할때는 isNaN을 사용해야 한다.

2. Double.isNaN

Double.isNaN(num);

true

isNaN 메소드는 boolean 타입으로, **Double.isNaN(value)**과 같이 사용하여 value가 NaN인지 아닌지 확인할 수 있다.



여기서 잠깐!

아래는 isNaN 메소드의 소스코드이다.

static public boolean isNaN(double v) {
    return (v != v);
}

v != v 가 자기 자신과 같은지 묻고 있으니 항상 false를 리턴할 것 같지만, v가 NaN이면 true를 리턴한다.
NaN의 사용은 IEEE 부동소수점 표준*에서 규정하고 있는데, 기본적인 의미를 이해하면 조금 쉽다.
NaN은 정의될 수 없고 나타낼 수 없는 값이다.**
정의될 수 없고 나타낼 수 없는 값 끼리 같다고 할 수 있을까?
따라서, 기본적으로 NaN값과 NaN값을 비교하는 건 항상 false이다.

  • IEEE754 : IEEE에서 개발한 컴퓨터에서 부동소수점을 표현하는 가장 널리 쓰이는 표준.
    ±0 등의 수와 무한NaN 등의 기호를 표시하는 법과 이러한 수에 대한 연산을 정의하고 있다.

근데 갑자기 궁금해졌다.


부동소수점이란?

위 NaN의 정의나, 그걸 규정하고 있는 IEEE754를 봐도 “부동소수점”이라는 걸 자주 언급한다.

💡 부동소수점
(浮動小數點, floating point) 또는 떠돌이 소수점 방식은 실수를 컴퓨터상에서 근사하여 표현할 때 소수점의 위치를 고정하지 않고 그 위치를 나타내는 수를 따로 적는 것으로, 유효숫자를 나타내는 가수(假數)와 소수점의 위치를 풀이하는 지수(指數)로 나누어 표현한다.

.. 말이 어렵다.
간단하게 얘기하면 “실수”, 즉 float, double 타입이라고 생각해도 좋을 듯 한데..?
어쨌든 정확한 계산을 위해서 부동소수점(실수)은 사용하지 않는 것이 좋다.

그렇지만 매번 실수 타입을 정수(int) 타입으로 형변환하는 건 귀찮지 않은가? 그럴 때 사용할 수 있는 자바 API가 있다.

BigDecimal

BigDecimal이라는 자바API를 사용하여 연산하면 정확한 수치 표현이 가능하다.

import java.math.BigDecimal;
public class BigDecimalExample {
	public static void main(String[] args) {
		BigDecimal decima1 = BigDecimal.valueOf(1);
		BigDecimal decima2 = BigDecimal.valueOf(0.7);
		System.out.println(decimal.subtract(decima2);
	}
}

0.3

다만 주의사항으로, BigDecimal은 String 생성자를 사용해야 정확한 수치 표현이 가능하다는 점! (보완필요)

실제로는 NaN값을 일부러 만들어내지 않는 한 많이 보게 될 지는 잘 모르겠지만,, 평소에 잘 모르고 지나갔던 점들을 정리해봤다! NaN값 체크는 isNaN이라는 것만 잘 기억하자.




참고

https://swrush.tistory.com/342
https://pancake.coffee/2018/03/25/double형의-값을-다룰-때-주의할-점-nan/
https://stackoverflow.com/questions/18442503/java-isnan-how-it-works
https://wikibook.co.kr/article/java-coding-with-pmd-badcomparison/
https://dimdim.tistory.com/entry/java-DoubleNaN-값-비교-연산-삽질
https://namu.wiki/w/컴퓨터에서의 수 표현?from=부동소수점#실수
https://ko.wikipedia.org/wiki/IEEE_754
https://learn.microsoft.com/ko-kr/dotnet/fundamentals/code-analysis/quality-rules/ca2242
https://reference-m1.tistory.com/105

profile
불타오르는 진루나

0개의 댓글