Java에서 제목과 같은 클래스는 숫자 포맷을 처리할 때 사용하는 클래스입니다.
잘못 사용하는 케이스가 있어 관련 내용 정리합니다.
DecimalFormat/NumberFormat 포맷 클래스는 별도로 RoundingMode를 설정하지 않을 시
디폴트 RoundingMode는 ROUND_HALF_EVEN 사용합니다.
현재 특정 함수중 numberFormat/numFormat 등이 DecimalFormat 클래스를
사용하고 있습니다. 별도의 RoundingMode를 적용하지 않아 디폴트인 ROUND_HALF_EVEN 사용하니
반올림 숫자 대상의 앞자리 숫자가 홀수냐 짝수냐에 따라 반올림이 되고 되지않는 현상이 발생합니다.
예)
DecimalFormat df = new DecimalFormat("#,###.00");
double rnd = 112399.405d;
System.out.println(df.format(rnd)); --> 112,399.40
df.setMaximumFractionDigits(2);
df.setRoundingMode(RoundingMode.HALF_UP);
System.out.println(df.format(rnd)); --> 112,399.41
주의) 테스트 해본 결과 현재 Oracle JDK의 경우 정상이나 Zulu JDK(OpenJDK)의 경우는 문제가 있음
OpenJDK를 사용하여 배포하는 JDK경우는 BigDecimal 클래스를 사용하여 처리해야 될것 같습니다.
(테스트 JDK : Zulu JDK, Zing JDK, AdoptOpenJDK, Amazon Corretto, RedHat JDK)
double rnd = 112399.405d;
DecimalFormat df = new DecimalFormat("#,###.00");
df.setRoundingMode(RoundingMode.HALF_UP);
df.setMaximumFractionDigits(2);
System.out.println(df.format(rnd)); --> 112,399.40
BigDecimal bd = new BigDecimal(rnd);
BigDecimal bd = BigDecimal.valueOf(rnd);
bd.setScale(2, RoundingMode.HALF_UP);
System.out.println(df.format(bd)); --> 112,399.41
** 참고(Java외에 다른 언어 또는 DBMS 등) **
ROUND_UP : 무조건 올림(0을 제외한 값)
ROUND_DOWN : 무조건 내림
ROUND_FLOOR : 무조건 내림 (음수일 경우에 무조건 올림)
ROUND_CEILING : 양수인 경우 올림(ROUND_UP), 음수인 경우 내림(ROUND_DOWN)
ROUND_HALF_UP : 반올림 ( >= 5보다 크거나 같으면 올림/ROUND_UP, 아니면 ROUND_DOWN)
ROUND_HALF_DOWN : 반올림 ( > 5보다 크면 올림/ROUND_UP, 아니면 ROUND_DOWN)
ROUND_HALF_EVEN : 반올림 (버릴 부분의 왼쪽 숫자가 홀수인 경우 ROUND_HALF_UP, 짝수인 경우 ROUND_HALF_DOWN)
참고 : https://www.ibm.com/support/knowledgecenter/ko/SSMKHH_10.0.0/com.ibm.etools.mft.doc/ak05380_.htm
https://docs.oracle.com/javase/6/docs/api/java/math/RoundingMode.html