Thursday, October 19, 2006
자바.Java] 실수 연산 특수값(특수숫자): NaN, Infinity 무한대
자바 연산에서 뭔가 특별한 값 (Something Special ?) 이 나오는 경우입니다.
파일명: Foo.java
어떤 숫자를 0으로 나누면 수학적 오류가 발생하기에 나눌 수 없지만, 실수 연산에서는 무한대라는 특수한 값 Infinity 가 나옵니다. 정수 0은 정확한 0이지만, 실수 0.0 은 완벽히 정확한 0이 아니기에 그런 것 같습니다.
만약 정수끼리 연산할 때, 정수 0으로 나누었다면 Exception in thread "main" java.lang.ArithmeticException: / by zero at Foo.main(Foo.java:5) "0으로 나누었습니다"라는 에러가 나지만, 0.0 같은 실수형 0(제로)이라면 에러가 나지 않고 특수 숫자 (Special Floating-Point Number) 인 Infinity 가 나옵니다.
그렇지만 0.0 / 0.0 은, 1.0이 나올 것이라고 생각했는데, 숫자가 아닌 NaN 으로 나오는군요.
0에 근접하는 숫자인 Double.MIN_VALUE 를 Double.MIN_VALUE 로 나누면 1.0 이 나옵니다.
분자와 분모가 똑같이 0에 근접하면 1이 나와야 할 텐데,
분자 분모가 0.0 이면 무조건 NaN 을 내는 것 같습니다.
"0으로 나누기"에 대한 재미있는(?) 읽을거리가 위키백과에 있더군요.
<Division by zero - Wikipedia>
파일명: Foo.java
public class Foo {
public static void main(String args[]) {
// NaN (Not A Number; 숫자가 아님) 이 출력되는 상황
System.out.println(0.0 / 0.0); // NaN
System.out.println(Math.sqrt(-2.0)); // NaN : 음수의 제곱근을 구할 때
System.out.println(Double.NaN); // NaN : 상수
// Infinity (무한대) 가 출력되는 상황
System.out.println(2.0 / 0.0); // Infinity
System.out.println(Double.MAX_VALUE * 2); // Infinity
System.out.println(Double.POSITIVE_INFINITY); // Infinity : 상수
System.out.println(Double.NEGATIVE_INFINITY); // -Infinity : 상수
// 네거티브 제로
System.out.println((-0.0) + (-0.0)); // -0.0
// 기타
System.out.println(Double.MIN_VALUE / Double.MIN_VALUE); // 1.0
System.out.println(Double.MIN_VALUE / 0.0); // Infinity
System.out.println(0.0 / Double.MIN_VALUE); // 0.0
// NaN 여부 판단하기
if (Double.isNaN(0.0 / 0.0)) System.out.println("NaN !!!");
// 이것은 잘못된 방법
// if ((0.0 / 0.0) == Double.NaN) System.out.println("NaN !!!");
// Infinity 여부 판단하기
if (Double.isInfinite(2.0 / 0.0)) System.out.println("Infinity !!!");
}
}
public static void main(String args[]) {
// NaN (Not A Number; 숫자가 아님) 이 출력되는 상황
System.out.println(0.0 / 0.0); // NaN
System.out.println(Math.sqrt(-2.0)); // NaN : 음수의 제곱근을 구할 때
System.out.println(Double.NaN); // NaN : 상수
// Infinity (무한대) 가 출력되는 상황
System.out.println(2.0 / 0.0); // Infinity
System.out.println(Double.MAX_VALUE * 2); // Infinity
System.out.println(Double.POSITIVE_INFINITY); // Infinity : 상수
System.out.println(Double.NEGATIVE_INFINITY); // -Infinity : 상수
// 네거티브 제로
System.out.println((-0.0) + (-0.0)); // -0.0
// 기타
System.out.println(Double.MIN_VALUE / Double.MIN_VALUE); // 1.0
System.out.println(Double.MIN_VALUE / 0.0); // Infinity
System.out.println(0.0 / Double.MIN_VALUE); // 0.0
// NaN 여부 판단하기
if (Double.isNaN(0.0 / 0.0)) System.out.println("NaN !!!");
// 이것은 잘못된 방법
// if ((0.0 / 0.0) == Double.NaN) System.out.println("NaN !!!");
// Infinity 여부 판단하기
if (Double.isInfinite(2.0 / 0.0)) System.out.println("Infinity !!!");
}
}
어떤 숫자를 0으로 나누면 수학적 오류가 발생하기에 나눌 수 없지만, 실수 연산에서는 무한대라는 특수한 값 Infinity 가 나옵니다. 정수 0은 정확한 0이지만, 실수 0.0 은 완벽히 정확한 0이 아니기에 그런 것 같습니다.
만약 정수끼리 연산할 때, 정수 0으로 나누었다면 Exception in thread "main" java.lang.ArithmeticException: / by zero at Foo.main(Foo.java:5) "0으로 나누었습니다"라는 에러가 나지만, 0.0 같은 실수형 0(제로)이라면 에러가 나지 않고 특수 숫자 (Special Floating-Point Number) 인 Infinity 가 나옵니다.
그렇지만 0.0 / 0.0 은, 1.0이 나올 것이라고 생각했는데, 숫자가 아닌 NaN 으로 나오는군요.
0에 근접하는 숫자인 Double.MIN_VALUE 를 Double.MIN_VALUE 로 나누면 1.0 이 나옵니다.
분자와 분모가 똑같이 0에 근접하면 1이 나와야 할 텐데,
분자 분모가 0.0 이면 무조건 NaN 을 내는 것 같습니다.
"0으로 나누기"에 대한 재미있는(?) 읽을거리가 위키백과에 있더군요.
<Division by zero - Wikipedia>
tag: java
자바 | Java 프로그래밍
square root 하는 value가 0보다 작아도 NaN이뜨네요....
음수의 square root는 실수가 아닌 복소수이기에 역시 NaN이 나옵니다.
<< Home