double a = 10.0000;
double b = 3.0000;
// 기대값: 13
// 실제값: 13.000001999999999
a + b;
// 기대값: 7
// 실제값: 6.999999999999999
a - b;
// 기대값: 30
// 실제값: 30.000013000000997
a * b;
// 기대값: 3.33333...
// 실제값: 3.333332555555814
a / b;
precision
: 숫자를 구성하는 전체 자리수라고 생각하면 편하나, 정확하게 풀이하면 왼쪽부터 0이 아닌 수가 시작하는 위치부터 오른쪽부터 0이 아닌 수로 끝나는 위치까지의 총 자리수 (ex: 012345.67890의 precision은 11이 아닌 9) = unscale
scale
: 전체 소수점 자리 수라고 생각하면 편하나, 정확하게 풀이하면 소수점 첫째 자리부터 오른쪽부터 0이 아닌 수로 끝나는 위치까지의 총 소수점 자리수이다. (ex: 012345.67890의 scale은 4이다. 하지만 0.00, 0.0의 scale은 모두 1이다.) BigDecimal은 32bit의 소수점 크기를 가진다. = fraction
DECIMAL128
: 부호와 소수점을 수용하며, 최대 34자리까지 표현 가능한 10진수를 저장할 수 있는 형식
거의 모든 금액을 수용할 수 있는 크기이다.
// 0
BigDecimal.ZERO
// 1
BigDecimal.ONE
// 10
BigDecimal.TEN
// double 타입을 그대로 초기화하면 기대값과 다른 값을 가진다.
// 0.01000000000000000020816681711721685132943093776702880859375
new BigDecimal(0.01);
// 문자열로 초기화하면 정상 인식
// 0.01
new BigDecimal("0.01");
// 위와 동일한 결과, double#toString을 이용하여 문자열로 초기화
// 0.01
BigDecimal.valueOf(0.01);
BigDecimal a = new BigDecimal("2.01");
BigDecimal b = new BigDecimal("2.010");
// 객체의 레퍼런스 주소에 대한 비교 연산자로 무의식적으로 값의 비교를 위해 사용하면 오동작
// false
a == b;
// 값의 비교를 위해 사용, 소수점 맨 끝의 0까지 완전히 값이 동일해야 true 반환
// false
a.equals(b);
// 값의 비교를 위해 사용, 소수점 맨 끝의 0을 무시하고 값이 동일하면 0, 적으면 -1, 많으면 1을 반환
// 0
a.compareTo(b);
BigDecimal a = new BigDecimal("10");
BigDecimal b = new BigDecimal("3");
// 더하기
// 13
a.add(b);
// 빼기
// 7
a.subtract(b);
// 곱하기
// 30
a.multiply(b);
// 나누기
// 3.333333...
// java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
a.divide(b);
// 나누기
// 3.333
a.divide(b, 3, RoundingMode.HALF_EVEN);
// 나누기 후 나머지
// 전체 자리수를 34개로 제한
// 1
a.remainder(b, MathContext.DECIMAL128);
// 절대값
// 3
new BigDecimal("-3").abs();
// 두 수 중 최소값
// 3
a.min(b);
// 두 수 중 최대값
// 10
a.max(b);
// 소수점 이하를 절사한다.
// 1
new BigDecimal("1.1234567890").setScale(0, RoundingMode.FLOOR);
// 소수점 이하를 절사하고 1을 증가시킨다.
// 2
new BigDecimal("1.1234567890").setScale(0, RoundingMode.CEILING);
// 음수에서는 소수점 이하만 절사한다.
// -1
new BigDecimal("-1.1234567890").setScale(0, RoundingMode.CEILING);
// 소수점 자리수에서 오른쪽의 0 부분을 제거한 값을 반환한다.
// 0.9999
new BigDecimal("0.99990").stripTrailingZeros();
// 소수점 자리수를 재정의한다.
// 원래 소수점 자리수보다 작은 자리수의 소수점을 설정하면 예외가 발생한다.
// java.lang.ArithmeticException: Rounding necessary
new BigDecimal("0.1234").setScale(3);
// 반올림 정책을 명시하면 예외가 발생하지 않는다.
// 0.123
new BigDecimal("0.1234").setScale(3, RoundingMode.HALF_EVEN);
// 소수점을 남기지 않고 반올림한다.
// 0
new BigDecimal("0.1234").setScale(0, RoundingMode.HALF_EVEN);
// 1
new BigDecimal("0.9876").setScale(0, RoundingMode.HALF_EVEN);
NumberFormat format = NumberFormat.getInstance();
format.setMaximumFractionDigits(6);
format.setRoundingMode(RoundingMode.HALF_EVEN);
// 0.123457
format.format(new BigDecimal("0.1234567890"));
foo DECIMAL(5,2) DEFAULT 0.00 NOT NULL