'실수'에 해당되는 글 1건

  1. 2015.03.13 BigDecimal 클래스 - 오차없이 실수 표현하기

실수형 데이터 타입을(float, double) 사용하여 값을 표현할 때에는 오차에 유의해야 합니다.

 

일반적인 프로그래밍에서 큰 영향이 없는 미묘한 차이일지라도 금융권 등에서는 치명적이 오류를 발생시키기 때문입니다.

 

자바의 BigDecimal 클래스을 사용하면 이러한 실수 표현의 문제점을 해결할 수 있습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import java.math.BigDecimal;
 
public class BigDecimalTest {
 
    public static void main(String[] args) {
        // test #1
        double value1 = 1.6;
        double value2 = 0.1;
        System.out.println("실수의 더하기 : " + (value1 + value2));
        System.out.println("실수의 곱하기 : " + (value1 * value2));
        System.out.println();
        
        // test #2
        BigDecimal value3 = new BigDecimal(1.6);
        BigDecimal value4 = new BigDecimal(0.1);
        System.out.println("BigDecimal 더하기 : " + value3.add(value4));    
        System.out.println("BigDecimal 곱하기 : " + value3.multiply(value4));    
        System.out.println();
        
        // test #3
        BigDecimal value5 = new BigDecimal("1.6");
        BigDecimal value6 = new BigDecimal("0.1");
        System.out.println("BigDecimal 더하기 : " + value5.add(value6));    
        System.out.println("BigDecimal 곱하기 : " + value5.multiply(value6));    
    }
}
cs

 

<결과>

실수의 더하기 : 1.7000000000000002
실수의 곱하기 : 0.16000000000000003

 

BigDecimal 더하기 : 1.7000000000000000943689570931383059360086917877197265625
BigDecimal 곱하기 : 0.1600000000000000177635683940025051398161724525855033823303533017413935457540219431393779814243316650390625

 

BigDecimal 더하기 : 1.7
BigDecimal 곱하기 : 0.16

 

 

1번째 테스트(test #1) 에서는 double 형 변수를 2개 생성하여 연산을 수행해 보았습니다.

예상된 결과는 더하기 : 1.7  곱하기 : 0.16 이지만 출력된 결과는 오차값을 표현하고 있습니다.

 

 

오차 문제를 해결하기 위해서 2번째 테스트(test #2) 에서 BigDecimal 클래스를 사용했습니다.

BigDecimal 은 math 패키지에 포함되어 있으며, 일반적인 클래스를 사용하듯이 new 키워드를 이용하여 객체를 생성한 후 add, multiply 메소드로 연산을 진행했습니다.

 

 

그런데 오차범위가 줄어들지 않고 오히려 더 상세하게 표현되고 있습니다!

BigDecimal 의 객체를 생성할 때 실수형 매개변수(1.6 과 0.1)가 전달되면서 이미 오차가 발생하기 때문에 더욱 심각한 연산 결과가 발생하게 되는 것입니다.

 

 

마지막으로 3번째 테스트(test #3) 에서는  BigDecimal 의 객체를 생성할 때 문자형 매개변수("1.6" 과 "0.1")가 전달되도록 작성해 보았습니다.

 

드디어 오차없이 정확한 결과값 1.7 과 0.16 이 출력되었습니다.

BigDecimal 클래스에는 add, multiply 이외에도 다양한 메소드가 제공되고 있으니 참고하시기 바랍니다.

 

 

 

Posted by maze1008
,