1. 소수점 연산은 항상 오류가 발생하니 주의할 것.  
Java Puzzler 에 나온 예제입니다. 2달러를 내고 1달러 10센트를 돌려받았습니다.
그럼 물건 가격은 얼마일까요?

public class Change {
public static void main(String args[]) {
System.out.println(2.00 - 1.10);
}
}




결과는 기막히게도 0.8999999999999999 입니다.
당연 오류입니다.
원하는 결과는 아니죠
해결하는 방법은 BigDecimal을 쓰는 방법입니다.
다시말해 정확한 계산을 해야한다면 자바에서는 BigDecimal을 써야만 합니다.  
보여주신 예중 하나를 실행해보면,
public class Test {
public static void main(String[] args) {
System.out.println(2.01 * 100);
}
}
결과값은 200.99999999999997 입니다.
이유는 0.01 이 표현이 안되기 때문입니다.
컴퓨터에서 부동 소수는 (1/2) * n1 + (1/4) * n2 + (1/8) * n3 + (1/16) * n4 ...  
위와 같은 합으로 표현됩니다.
그리고 불행히도 0.01은 이런 값의 합으로 표현할 수가 없습니다.
대략 2.5 = 2 + 1/2, 2.25 = 2 + 1/4 와 같은 수는 표현이 가능해서 제대로 출력이 됩니다.
문제는 컴퓨터에서의 부동소수는 작은 수의 범위는 촘촘하고,
큰 수의 범위는 띄엄띄엄합니다.

public class Test {
public static void main(String[] args) {
double i = 1.0e30;
System.out.println( i == i + 1 );
}
}
이 프로그램의 결과는 true입니다.
무지 큰수 + 1 = 무지 큰수가 됩니다. 
수가 커지면 수 간의 간격도 커져서 1 정도 더해서는 값에 변화도 생기지 않습니다.
그래서 정확한 값을 쓰려면, BigDecimal을 써야만 합니다.
또, BigDecimal을 쓰실 때 인자를 String으로 주어야하는데 유의해야 합니다.
예를들어,  


import java.math.*;
public class Test {
public static void main(String[] args) {
BigDecimal b = new BigDecimal(2.01);
BigDecimal b2 = new BigDecimal("2.01");
System.out.println(b.toString());
System.out.println(b2.toString());
}
}
의 실행결과는
2.0099999999999997868371792719699442386627197265625  
2.01 입니다.

애초에 2.01이라는 상수를 프로그램내에 쓰면 그 정확한 값 자체가 안넘어옵니다.
따라서 문자열로 인자를 사용해야만 합니다.


출처 javaservice.net - 좋은 내용 같아서요..




Posted by
,