JAVA

BigDecimal

쿠키는고양이 2022. 8. 28. 16:01

 

소수점을 취급할 때 대부분의 프로그래밍 언어에서 지원해주는 Float, Double 를 보통 많이 사용하였다.

평범하게 사용한다면 소수점 아래의 수는 워낙 작아 큰 문제가 없었지만, 돈과 관련된 데이터를 취급하는 과정에서

0.001 정도의 오차로 인해 큰 문제가 생길 뻔 했다.

 

BigDecimal은 현재 자바 내에서 유리수를 표현하는 가장 정밀한 방법이다.

Float와 Double을 연산하게 된다면 부동소수점의 문제로 약간의 오차가 발생하는데

단 1원의 차이도 용납 안되는 금융 데이터에서는 반드시 BigDecimal 을 사용하여야 한다.

 

1. BigDecimal 초기화 및 상수

초기화는 생성자를 통한 초기화로 가능하다.

초기화할 경우 주의할 점은 파라미터로 Double Type 값을 넘겨 줄 경우 아래와 같이 문제가 발생한다.

5.01 로 초기화를 원했으나 5.00999999... 으로 나오게 된다.

Double 타입 값은 2진수로 변환되어 표현할 값과 가장 근사치로 계산되어 오차가 발생한다.

(BigDecimal은 10진수로 계산되어 가장 정확한 값을 나타낼 수 있다.)

이를 막기 위해서는 String Type 으로 파라미터를 전달하면 된다.

 

BigDecimal 에서 제공하는 기본 상수를 활용( ZERO, ONE, TEN )이 가능하다.

import java.math.BigDecimal;

public class BigDecimalTest {


	public static void main(String[] args) {
		
		BigDecimal bigInit1 = new BigDecimal(5);
		BigDecimal bigInit2 = new BigDecimal(5.01);
		BigDecimal bigInit3 = new BigDecimal("5.0");
		
		// 초기화
		System.out.println("Constructor Init : " + bigInit1);
		
		System.out.println("Double Type Construct : " + bigInit2);
		
		System.out.println("String Type Construct : " + bigInit3);
		
		// 상수
		bigInit1 = BigDecimal.ZERO;
		System.out.println("Zero Const : " + bigInit1);
		
		bigInit1 = BigDecimal.ONE;
		System.out.println("ONE Const: " + bigInit1);
		
		bigInit1 = BigDecimal.TEN;
		System.out.println("TEN Const: " + bigInit1);
	}
}
 
 

2. BigDecimal 사칙 연산

BigDecimal로 사칙연산은 메소드 호출 방식으로 이루어진다.

사용하는 메소드는 다음과 같다.

ADD , SUBTRACT, MULTIPLY, DIVIDE

import java.math.BigDecimal;

public class BigDecimalTest {
	public static void main(String[] args) {
		
		BigDecimal bigInit1 = new BigDecimal(5.0);
		BigDecimal bigInit2 = new BigDecimal(5.01);
		BigDecimal bigInit3 = new BigDecimal("5.001");
		
		// 덧셈
		System.out.println("ADD : " + bigInit1.add(bigInit3));
		// 뺄셈
		System.out.println("SUBTRACT : " + bigInit1.subtract(bigInit3));
		// 곱셈
		System.out.println("MULTIPLY : " + bigInit1.multiply(bigInit3));
		// 나눗셈 (5.001 / 5)
		System.out.println("DIVIDE : " + bigInit3.divide(bigInit1));
		// 나눗셈 (5 / 5.001)
		System.out.println("DIVIDE : " + bigInit1.divide(bigInit3));

	}
}
 

정수와 유리수의 나눗셈의 경우 연산자, 피연산자에 따라서 표현식 오류가 발생할 수 있다.

 

3. BigDecimal 비교 연산자

import java.math.BigDecimal;

public class BigDecimalTest {

	public static void main(String[] args) {
		
		BigDecimal bigInit1 = new BigDecimal(5.0);
		BigDecimal bigInit2 = new BigDecimal(5);
		BigDecimal bigInit3 = new BigDecimal("5.001");
		
		// Equals
		System.out.println("Equals : " + bigInit1.equals(bigInit2));

		// compareTo 1
		System.out.println("CompareTo : " + bigInit1.compareTo(bigInit2));
		
		// compareTo 2
		System.out.println("CompareTo : " + bigInit2.compareTo(bigInit3));
		
		// compareTo 3
		System.out.println("CompareTo : " + bigInit3.compareTo(bigInit2));
		
		// Max
		System.out.println("Max : " + bigInit1.max(bigInit3));
		
		// Min
		System.out.println("Min: " + bigInit1.min(bigInit3));
		
	}
}
 

동일 여부 확인은 BigDecimal 객체를 비교하므로 eqauls 로 비교한다.

CompareTo 의 경우 연산자와 피연산자 비교하여 같으면 0 작으면 -1 크면 1을 반환한다.

 

더 자세한 사항은 아래 블로그를 참고

https://jsonobject.tistory.com/466

이미지 썸네일 삭제
Java, BigDecimal 사용법 정리

BigDecimal? BigDecimal은 Java 언어에서 숫자를 정밀하게 저장하고 표현할 수 있는 유일한 방법이다. 소수점을 저장할 수 있는 가장 크기가 큰 타입인 double은 소수점의 정밀도에 있어 한계가 있어 값이 유실될..

jsonobject.tistory.com