CodeGym /행동 /JAVA 25 SELF /숫자의 반올림과 서식 지정

숫자의 반올림과 서식 지정

JAVA 25 SELF
레벨 6, 레슨 4
사용 가능

1. 소개

현실에서는 소수점 이하에 긴 “꼬리”를 볼 필요가 거의 없습니다. 예를 들어 상품 가격, 급여, 평균 점수, 방의 면적을 계산할 때는 보통 소수점 이하 한두 자리면 충분하지, 15자리까지 볼 필요는 없습니다.

예를 들어, 나눗셈 결과:

double x = 10.0 / 3.0;
System.out.println(x); // 3.3333333333333335

사용자는 이런 결과를 보면 당황해서 프로그램이 잘못되었다고 생각할 수 있습니다. 따라서 숫자는 종종 반올림이 필요합니다 — 가장 가까운 정수, 소수점 이하 두 자리 등으로요.

Java에는 이를 위한 편리한 도구들이 여러 가지 있습니다.

2. 메서드 Math.round(): 가장 가까운 정수로 반올림

숫자를 반올림하는 가장 간단한 방법은 Math.round() 메서드를 사용하는 것입니다. 이 메서드는 부동소수점 숫자(float와 double 모두)를 받아 가장 가까운 정수를 반환합니다.

Math.round의 동작 방식

  • 소수 부분이 0.5보다 작으면 — 내림.
  • 소수 부분이 0.5 이상이면 — 올림.

예시:

System.out.println(Math.round(2.3)); // 2
System.out.println(Math.round(2.7)); // 3
System.out.println(Math.round(2.5)); // 3
System.out.println(Math.round(-2.5)); // -2

반환 타입

  • float을 전달하면 int가 반환됩니다.
  • double을 전달하면 long이 반환됩니다.
float f = 5.8f;
int roundedF = Math.round(f); // 6

double d = 5.8;
long roundedD = Math.round(d); // 6

주의: 가끔 놀랄 수 있습니다 — double을 반올림했는데 결과가 long입니다! int가 필요하다면 명시적 캐스팅이 필요합니다:

int rounded = (int) Math.round(5.6); // 6

3. 원하는 소수 자릿수로 반올림

정수가 아니라, 예를 들어 소수점 이하 두 자리(금액, 퍼센트 등)로 반올림해야 할 때가 자주 있습니다.

Java에는 Math.roundTo2Digits() 같은 “마법의” 메서드는 없지만, 수학적으로 처리하면 됩니다.

방법 1: 곱하고 나누는 수학적 트릭

  1. 숫자에 100을 곱합니다(두 자리가 필요하다면).
  2. Math.round로 정수로 반올림합니다.
  3. 다시 100으로 나눕니다.

예:

double value = 3.14159;
double rounded = Math.round(value * 100.0) / 100.0;
System.out.println(rounded); // 3.14

동작 원리:

  • 3.14159 * 100 = 314.159
  • Math.round(314.159) = 314
  • 314 / 100.0 = 3.14

4. 숫자 서식 지정: 클래스 DecimalFormat

때로는 숫자를 반올림하는 것뿐 아니라 보기 좋게 출력해야 합니다 — 소수 자릿수 고정, 앞자리 0 채우기, 천 단위 구분 기호 등. 이를 위해 Java에는 java.text 패키지의 DecimalFormat 클래스가 있습니다.

DecimalFormat의 동작 방식

  1. 원하는 패턴으로 객체를 생성합니다.
  2. 그 객체의 format(...) 메서드를 호출합니다.
import java.text.DecimalFormat;

double value = 3.14159;

DecimalFormat df = new DecimalFormat("0.00");
System.out.println(df.format(value)); // 3.14

패턴 구성

  • "0.00" — 항상 소수점 이하 두 자리를 표시합니다(숫자가 정수여도).
  • "0.###" — 소수점 이하 최대 세 자리까지 표시하며, 불필요한 0은 생략합니다.
  • "#,##0.00" — 천 단위 구분 기호를 추가합니다(예: "1,234.56").

다양한 패턴 예:

패턴 숫자 결과
"0.00"
2 2.00
"0.00"
2.5 2.50
"0.00"
2.567 2.57
"0.###"
2.567 2.567
"0.###"
2.5 2.5
"#,##0.00"
12345.678 12,345.68

천 단위 구분 기호 예

DecimalFormat df = new DecimalFormat("#,##0.00");
System.out.println(df.format(1234567.89)); // 1,234,567.89

예: 불필요한 0 없이 출력

DecimalFormat df = new DecimalFormat("0.##");
System.out.println(df.format(3.1));   // 3.1
System.out.println(df.format(3.141)); // 3.14
System.out.println(df.format(3.145)); // 3.15

5. String.format으로 서식 지정

간단한 경우에는 String.format을 사용하는 것이 편리합니다 — 다른 언어의 printf와 유사한 내장 문자열 서식 지정 방식입니다.

double value = 3.14159;
System.out.println(String.format("%.2f", value)); // 3.14

여기서 "%.2f" — “소수점 이하 두 자리로 출력”을 의미합니다.

접근 방식 비교:

  • DecimalFormat — 더 강력하며, 패턴과 로캘을 지원하고 천 단위 구분에 유용합니다.
  • String.format — 소수 자릿수만 간단히 지정할 때 더 쉽습니다.

6. 반올림 관련 메서드: Math.floor, Math.ceil, Math.rint

  • Math.floor(x) — 내림(작은 쪽으로 반올림)하며, 음수에도 동일하게 적용됩니다.
  • Math.ceil(x) — 올림(큰 쪽으로 반올림)합니다.
  • Math.rint(x) — 가장 가까운 정수로 반올림하지만, 반환 타입은 double입니다.

예시:

System.out.println(Math.floor(2.7)); // 2.0
System.out.println(Math.ceil(2.1));  // 3.0
System.out.println(Math.rint(2.5));  // 2.0 (맞습니다, 오타가 아닙니다!)
System.out.println(Math.rint(3.5));  // 4.0

주의: Math.rint는 때때로 “가장 가까운 짝수”로 반올림합니다 — 이 규칙(소위 banker's rounding)은 대량 계산 시 누적 오차를 줄이는 데 도움이 됩니다.

7. 유용한 포인트

시각화: 반올림 표

숫자 Math.round Math.floor Math.ceil Math.rint
2.3 2 2.0 3.0 2.0
2.5 3 2.0 3.0 2.0
3.5 4 3.0 4.0 4.0
-2.3 -2 -3.0 -2.0 -2.0
-2.5 -2 -3.0 -2.0 -2.0

반올림은 서식 지정이 아니다!

반올림과 서식 지정의 차이를 이해하는 것이 매우 중요합니다.

  • 반올림 — 숫자 값 자체를 변경합니다(예: 2.718 → 2.72).
  • 서식 지정 — 출력 형태만 바꿉니다(예: 화면에는 "2.72"로 보이지만, 메모리에는 여전히 2.718이 남습니다).
double x = 2.718;
System.out.println(String.format("%.2f", x)); // 2.72
System.out.println(x); // 2.718

반올림된 숫자를 이후 계산에 사용할 계획이라면 — 수학적으로 반올림하세요! 출력용으로만 필요하다면 — 서식만 지정하면 됩니다.

8. 숫자 반올림/서식 지정에서 흔히 하는 실수

오류 №1: 출력에만 반올림하고 이후 계산에는 “꼬리가 긴” 숫자를 사용.
아주 흔한 상황입니다 — 화면에는 보기 좋게 서식화된 값을 보여주고, 그다음 계산에서는 원래의 “긴” 숫자를 사용하는 경우죠. 금액, 점수, 합계 등에서는 — 먼저 반올림(Math.round나 곱셈/나눗셈 기법)을 수행한 뒤 저장하거나 사용자에게 전달하세요.

오류 №2: Math.round(x)가 소수점 이하 두 자리의 double을 반환할 것이라고 기대.
Math.round()는 항상 가장 가까운 정수로 반올림합니다: float에 대해선 int, double에 대해선 long을 반환합니다. 소수점 이하 두 자리가 필요하면 곱셈/나눗셈 트릭이나 서식 지정을 사용하세요.

오류 №3: 계산에 DecimalFormat을 사용.
DecimalFormat.format()은 문자열을 반환합니다. 이를 산술 연산에 사용할 수 없습니다: 컴파일 에러가 나거나 역파싱 시 NumberFormatException이 발생합니다.

오류 №4: 잘못된 DecimalFormat 패턴.
패턴은 의도에 맞아야 합니다: "0.00"은 항상 두 자리를 표시("2.00")하고, "0.##"는 불필요한 0을 제거합니다("2", "2.1", "2.12").

오류 №5: 100으로 나눌 때의 정밀도 손실.
int를 int로 나누면 결과도 int입니다!

int a = 5;
System.out.println(a / 2); // 2 (2.5가 아닙니다!)

나눗셈이 “실수 나눗셈”이 되려면, 피연산자 중 하나는 double이어야 합니다:

int a = 5;
System.out.println(a / 2.0); // 2.5
1
과제
JAVA 25 SELF, 레벨 6, 레슨 4
잠금
우주 식민지 자원 평가 🛰️
우주 식민지 자원 평가 🛰️
1
과제
JAVA 25 SELF, 레벨 6, 레슨 4
잠금
세금을 포함한 엘릭서 가격 정확 계산하기 💰
세금을 포함한 엘릭서 가격 정확 계산하기 💰
1
과제
JAVA 25 SELF, 레벨 6, 레슨 4
잠금
분기 수익 보고서를 보기 좋게 표시하기 📊
분기 수익 보고서를 보기 좋게 표시하기 📊
1
과제
JAVA 25 SELF, 레벨 6, 레슨 4
잠금
세계 판매액을 보기 쉬운 형식으로 표시하기 🌍
세계 판매액을 보기 쉬운 형식으로 표시하기 🌍
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION