NaN

덤프버전 :


파일:나무위키+넘겨주기.png   관련 문서: 컴퓨터/표현



1. 개요
2. 필요성
3. 문제점
4. 각종 언어에서의 NaN 예시



1. 개요[편집]


Not a Number, NaN[1]

NaN은 잘못된 입력으로 인해 계산을 할 수 없음을 나타내는 기호이다. 이를테면 음수의 제곱근을 구하려고 한다거나, 수만 나타낼 수 있는 변수에 텍스트를 넣었을때 일어나며, 일부 언어에서는 0으로 나눈 몫을 구하려고 할 때 예외를 던지는 대신 NaN을 반환하기도 한다. 이는 실수만을 저장할 수 있는 기본 부동소수점 저장체계에는 저장할 수 없는 허수나 실존하지 않는 수를 저장할 수 없기 때문에 오류 대신 반환하는 리턴값이다.

JavaScript에서는 숫자와 문자를 연산하거나, 숫자가 아닌 수를 파싱하려 할 때 주로 리턴되며, Java에서는 부정형[2]을 계산하려 하거나 Math 함수로 연산시 잘못된 값(제곱근 함수에 음수 입력 등)이 들어가면 주로 리턴된다. (자바스크립트에서 0이 아닌 숫자를 0으로 나누면
Infinity
가 나오며, 자바에서도 double이나 float에서 0으로 나누면 동일한 결과가 나온다.[3])

그리고 무한이라는 뜻은 아니다. 물론 무한으로 취급되는 경우가 많긴 하다. 하지만 어떤 경우에는 0보다 못한 음의 무한이 될 수도 있다. 만약 돈이 NaN이면 물건을 무한히 살 수 있지만 최소 0보다 커야 하는 값이 NaN이면 오히려 0만도 못하다.

2. 필요성[편집]


어떤 사람은 NaN 대신 예외를 던지는게 더 나을 것이라고 생각할 수도 있다. 하지만 꼭 그런것만은 아닌게 사용자가 입력을 한 값을 프로그램의 알고리즘에 대입을 했을 때 개발자가 예상치 못한 오류는 항상 생길 수 있으며 그럴 때마다 프로그램이 오류를 뿜으려 종료되는 것은 좋지 못하기 때문에 일단 프로그램은 잘 돌아가도록 NaN을 반환하는게 이득일 때도 있다.


3. 문제점[편집]


자바스크립트에서, NaN은 참 NaN인지 알아내기 어려운 값이다.
x == NaN
같은 비교 연산으로 알아낼 수 있나 싶겠지만,
NaN == NaN
false
가 나오는 것을 확인할 수 있고, 일치 연산자 ===를 사용해도
NaN === NaN
은 false가 나온다[* 역설적으로, 이걸 이용해 NaN을 구분하는 함수를 만들 수 있다!
const isNaN2 = _ => _ !== _
]. 전역 함수로 isNaN()이 있지만, 이 함수는 정확히 말하면 '어떤 값이 숫자로 변환될 수 있는지'를 알려주는 함수인 데에다, null
false
로 판단하는 등의 문제가 있었다. (이 문제는 ES6에서
Number.isNan()
함수가 나오며 해결되었다.)

하지만 자바스크립트에선 여전히 마땅히 예외가 발생해야 할 이상한 연산에서도 NaN이 나오고 마는 경우가 있어 디버깅이 어려워지는 등의 문제가 있다.

수학적으로 보면 이 개념이 이상하게 보일 수 있다. [math(\sqrt{-0} = {\sf NaN})]이라면 말이 되는가?[4]

4. 각종 언어에서의 NaN 예시[편집]


  • C\#[5]

'b' + 'a' + + 'n' + 'a' // baNaNa



상기 코드에서 "print(y == Double.nan)" 코드는 false를 내뱉지만, print(y.isNaN) 코드는 true를 출력한다. 일반적인 상황에서 Swift는 NaN 에러를 출력하지 않지만,
을 변수명 뒤에 붙이는 것으로 해당 변수가 숫자인지, 숫자가 아닌지 Bool값을 출력할 수 있다. 숫자가 아니면 true, 숫자라면 false. 이렇게 복잡한 이유는, Swift는 NaN을 Float값의 하나로 처리하기 때문. 코드 출처
이와 같은 논리로, 하기 코드도 NaN으로 인식된다.
다만, 일부 언어와 달리 단순 print(0/0)을 돌려도 NaN이 출력되지는 않고, print(0.0/0.0)을 실행해야 nan이 출력된다. 이 역시 상술했듯 Swift에서 NaN을 Int가 아닌 Float(혹은 Double)의 일환으로 처리하기 때문. 단순히 Int값으로 0/0을 출력하려고 하면 "error: division by zero"로 컴파일 에러가 발생한다.
파일:크리에이티브 커먼즈 라이선스__CC.png 이 문서의 내용 중 전체 또는 일부는 2023-10-31 13:25:51에 나무위키 NaN 문서에서 가져왔습니다.

[1] N이 2개 있지만 서로 다른 뜻이다.[2] 0 / 0, Infinity * 0, Infinity - Infinity, Infinity / Infinity 등. 물론 2의 1024제곱 이상의 모든 수는 무한으로 취급한다. 반대로 5e-324보다 작아지면 0으로 취급한다. 그리고 현재 값의 10경 분의 1도 안되는 값은 더하거나 빼는 건 아예 안 한 것과 같은 것으로 취급한다.[3] 단, int 등 정수값의 경우 java.lang.ArithmeticException: / by zero 예외가 발생한다.[4] 수학적으로는 그냥 [math(0)]이다.[5] 다음 두 줄의 코드는 모두 NaN을 출력한다.