금융 계산을 위한 BigDecimal
금액과 세금 계산에서 부동 소수점 정밀도 오류를 피하기 위해 BigDecimal을 사용합니다.
금융 계산을 위한 BigDecimal은(는) CoddyKit의 무료 Java Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Java Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
재무 계산을 위한 BigDecimal
부동 소수점 형식(double, float)은 이진 표현 때문에 모든 십진수 값을 정확하게 표현할 수 없습니다. 금액과 세금에는 BigDecimal을 사용합니다.
부동 소수점의 문제
이진 부동 소수점은 아주 작은 반올림 오류를 만듭니다. 재무 애플리케이션에서는 이러한 오류가 누적되어 실제 버그를 일으킵니다.
double price = 0.1 + 0.2;
System.out.println(price); // 0.30000000000000004 (WRONG!)
System.out.println(price == 0.3); // false
// Real bug: total never equals expected
double total = 0;
for (int i = 0; i < 10; i++) total += 0.1;
System.out.println(total); // 0.9999999999999999BigDecimal을 안전하게 생성하기
항상 double이 아니라 String에서 BigDecimal을 생성합니다. double 생성자를 사용하면 부동 소수점의 부정확성이 그대로 이어집니다.
import java.math.BigDecimal;
// WRONG: double constructor
BigDecimal wrong = new BigDecimal(0.1);
System.out.println(wrong); // 0.1000000000000000055511...
// CORRECT: String constructor
BigDecimal correct = new BigDecimal("0.1");
System.out.println(correct); // 0.1
// Or use valueOf (also safe)
BigDecimal safe = BigDecimal.valueOf(0.1);
System.out.println(safe); // 0.1BigDecimal 기본 산술 연산
BigDecimal은 산술 연산에 메서드 호출을 사용합니다. 즉, add(), subtract(), multiply(), divide()를 사용합니다. 이러한 호출은 새로운 BigDecimal 인스턴스를 반환합니다(불변).
import java.math.BigDecimal;
BigDecimal price = new BigDecimal("19.99");
BigDecimal tax = new BigDecimal("0.08");
BigDecimal qty = new BigDecimal("3");
BigDecimal subtotal = price.multiply(qty);
BigDecimal taxAmount = subtotal.multiply(tax);
BigDecimal total = subtotal.add(taxAmount);
System.out.println(subtotal); // 59.97
System.out.println(taxAmount); // 4.7976
System.out.println(total); // 64.7676반올림 방식
RoundingMode는 BigDecimal의 반올림 방식을 제어합니다. 주요 방식은 다음과 같습니다:
HALF_UP— 일반적인 반올림(0.5는 올림)HALF_EVEN— 은행가 반올림(0.5를 가장 가까운 짝수로 반올림)DOWN— 0을 향해 버림CEILING— 양의 무한대를 향해 반올림
import java.math.*;
BigDecimal val = new BigDecimal("2.565");
System.out.println(val.setScale(2, RoundingMode.HALF_UP)); // 2.57
System.out.println(val.setScale(2, RoundingMode.HALF_EVEN)); // 2.56 (banker's)
System.out.println(val.setScale(2, RoundingMode.DOWN)); // 2.56
System.out.println(val.setScale(2, RoundingMode.CEILING)); // 2.57나눗셈과 소수 자릿수
BigDecimal로 나눗셈을 수행할 때는 끝나지 않는 소수로 인한 ArithmeticException을 방지하기 위해 소수 자릿수와 반올림 방식을 지정해야 합니다.
import java.math.*;
BigDecimal revenue = new BigDecimal("1000.00");
BigDecimal months = new BigDecimal("3");
// Without scale → ArithmeticException (non-terminating decimal)
try {
revenue.divide(months);
} catch (ArithmeticException e) {
System.out.println("Need to specify scale!");
}
// Correct: specify scale and rounding
BigDecimal monthly = revenue.divide(months, 2, RoundingMode.HALF_UP);
System.out.println(monthly); // 333.33BigDecimal 비교하기
값을 비교할 때는 equals()가 아니라 compareTo()를 사용합니다. equals()는 소수 자릿수까지 고려합니다. 즉, 2.0과 2.00은 equals()로는 NOT 같지만 compareTo()로는 ARE 같습니다.
import java.math.BigDecimal;
BigDecimal a = new BigDecimal("2.0");
BigDecimal b = new BigDecimal("2.00");
System.out.println(a.equals(b)); // false (different scale)
System.out.println(a.compareTo(b)); // 0 (same value)
System.out.println(a.compareTo(b) == 0); // true
// For sorting in collections
import java.util.*;
List<BigDecimal> prices = Arrays.asList(
new BigDecimal("3.50"), new BigDecimal("1.00"), new BigDecimal("2.75")
);
Collections.sort(prices);
System.out.println(prices); // [1.00, 2.75, 3.50]유효 자릿수를 위한 MathContext
MathContext는 정밀도(유효 자릿수)와 반올림 방식을 지정합니다. 소수점 이하 자릿수가 아니라 일관된 유효 자릿수 정밀도가 필요할 때 사용합니다.
import java.math.*;
MathContext mc = new MathContext(4, RoundingMode.HALF_UP);
BigDecimal a = new BigDecimal("1234567");
BigDecimal b = new BigDecimal("3");
BigDecimal result = a.divide(b, mc);
System.out.println(result); // 4.115E+5 (4 significant digits)
// DECIMAL32, DECIMAL64, DECIMAL128 are standard MathContexts
BigDecimal precise = new BigDecimal("355").divide(
new BigDecimal("113"), MathContext.DECIMAL64);
System.out.println(precise); // 3.141592920353982...장바구니 예제
항목, 세금, 할인 및 최종 합계를 BigDecimal로 계산하는 완전한 장바구니 예제입니다.
import java.math.*;
record LineItem(String name, BigDecimal price, int qty) {
BigDecimal subtotal() {
return price.multiply(new BigDecimal(qty));
}
}
var items = List.of(
new LineItem("Laptop", new BigDecimal("999.00"), 1),
new LineItem("Case", new BigDecimal("29.99"), 2),
new LineItem("Charger", new BigDecimal("49.99"), 1)
);
BigDecimal subtotal = items.stream()
.map(LineItem::subtotal)
.reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal taxRate = new BigDecimal("0.09");
BigDecimal tax = subtotal.multiply(taxRate).setScale(2, RoundingMode.HALF_UP);
BigDecimal total = subtotal.add(tax);
System.out.println("Subtotal: " + subtotal);
System.out.println("Tax: " + tax);
System.out.println("Total: " + total);Stripe: 센트 단위 통화
Stripe와 같은 결제 처리기는 소수 관련 문제를 완전히 피하기 위해 금액을 정수 센트로 저장합니다. 센트와 화면에 표시할 금액 사이를 변환하는 것은 일반적인 패턴입니다.
import java.math.*;
// Store as cents (long) for database / API
long amountCents = 999_99L; // $999.99
// Convert to BigDecimal for display
BigDecimal amount = BigDecimal
.valueOf(amountCents)
.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
System.out.println("Amount: $" + amount); // Amount: $999.99
// Convert user input back to cents
BigDecimal input = new BigDecimal("49.95");
long cents = input.multiply(new BigDecimal("100"))
.setScale(0, RoundingMode.HALF_UP).longValueExact();
System.out.println("Cents: " + cents); // Cents: 4995BigDecimal과 double 중 선택하기
작업에 맞는 형식을 선택합니다:
- BigDecimal: 정확한 십진수 표현이 중요한 재무 금액, 세금, 청구서
- double: 속도가 중요하고 작은 오류를 허용할 수 있는 과학 계산, 그래픽, ML
- int/long 센트: 결제 API 및 데이터베이스의 금액 저장
빠른 확인
소수 자릿수와 관계없이 두 BigDecimal 값이 수치상 같은지 확인하려면 어떤 BigDecimal 비교 메서드를 사용해야 합니까?
복습: 재무 계산을 위한 BigDecimal
핵심 내용:
- double/단정밀도 부동 소수점형은 반올림 오류를 일으키므로 금액에 절대 사용하지 않습니다
- double이 아니라 String 또는
BigDecimal.valueOf()에서 BigDecimal을 생성합니다 - 산술 연산에는
add(),subtract(),multiply(),divide()를 사용합니다 - 나눗셈을 수행할 때는 항상 소수 자릿수와
RoundingMode를 지정합니다 - 같음 여부를 확인할 때는
equals()가 아니라compareTo()를 사용합니다 - 데이터베이스나 API 작업에서는 금액을 정수 센트로 저장하는 방법을 고려합니다
자주 묻는 질문
“금융 계산을 위한 BigDecimal” 강의는 무료인가요?
네 — “금융 계산을 위한 BigDecimal” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Java Academy 강의 전체를 잠금 해제할 수 있습니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“금융 계산을 위한 BigDecimal”에서 뭘 배우나요?
금액과 세금 계산에서 부동 소수점 정밀도 오류를 피하기 위해 BigDecimal을 사용합니다. 브라우저에서 직접 실행하는 실습 코드로 Java Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Java Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Java Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“금융 계산을 위한 BigDecimal” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Java Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Java Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- Math 클래스 핵심
- 정수 연산과 오버플로
- 금융 계산을 위한 BigDecimal
- NumberFormat과 printf