본문 바로가기
목차
Python

rounding 종류: C, Java, Python - Banker's Rounding

by ds31x 2025. 8. 9.
728x90
반응형

일반적으로 수학에서의 반올림은 half away from zero로,

tie(=half)에서 0에서 멀어지는 방향(절대값이 커지는 방향)으로 처리됨.

 

프로그래밍 언어에선 round 함수의 동작이 half에서 조금씩 차이가 있음:

  • Java: half toward positive infinity 방식 (Oracle 공식 문서)
    • 절댓값이 tie 보다 크면 부호방향으로 올림, 작으면 0방향으로 내림.
    • 모든 tie에서 positive infinity 방향으로 일관되게 처리
  • Python: half to even 방식이 기본
    • 절댓값이 tie 보다 크면 부호방향으로 올림, 작으면 0방향으로 내림.
    • ties에서 가장 가까운 짝수값으로
  • C (C99): half away from zero (수학에서 다루는 반올림)
    • 절댓값이 tie 보다 크면 부호방향으로 올림, 작으면 0방향으로 내림.
    • 절댓값이 ties 에선 0에서 멀어지는 방향으로 이동.

예를 들어
소수 첫째 자리에서 rounding을 하는 경우
ties는 .5인 경우임.

src Java (Math.round) C (round) Python (round)
2.6 3 3 3
2.5 3 3 2
1.5 2 2 2
1.3 1 1 1
0.5 1 1 0
-0.5 0 -1 0
-1.3 -1 -1 -1
-1.5 -1 -2 -2
-2.5 -2 -3 -2
-2.6 -3 -3 -3

Banker's Rounding: Rounding Half to Even

Python의 built-in 함수인 round()의 방식은 Banker's rounding이라는 별칭을 가짐.

  • 수학적 반올림은 .5가 항상 0에서 멀어지기 때문에, 많은 데이터 집계에서 미세하게 (절대)값이 커지는 방향으로 누적 오차(bias)가 생김.
  • 반면 Banker’s rounding은 .5(tie or half) 케이스의 절반은 올리고, 절반은 내림으로 처리하므로 bias가 줄어드는 장점이 있음.
  • 금융과 통계에서 보다 유리함.

https://www.youtube.com/watch?app=desktop&v=xBAkyXZXHqo


참고

  • Java는
    • Math.round()는 half toward positive infinity 로 고정 동작이나,
    • BigDecimal로 여러 모드(예: HALF_UP, HALF_EVEN, HALF_DOWN, UP, DOWN 등) 지정 가능.
  • Python은
    • 내장 round()는 half to even 고정 동작이나,
    • decimal.Decimalgetcontext().rounding을 사용하면
      • ROUND_HALF_EVEN,
      • ROUND_HALF_UP(=half away from zero),
      • ROUND_HALF_DOWN,
      • ROUND_UP,
      • ROUND_DOWN(=toward zero) 등 다양한 모드 지정 가능.
  • C는
    • 표준 round()가 half-away-from-zero 고정
    • Banker’s rounding 와 같은 다른 모드가 필요하면 nearbyint(), trunc(), floor() 같은 다른 표준 함수나 직접 구현 사용해야 함.
from decimal import Decimal, getcontext

values = ['-2.6', '-2.5', '-2.3', '-1.6','-1.5','-1.3', '-0.6','-0.5','-0.3','0.3','0.5','0.6','1.3','1.5','1.6', '2.3', '2.5', '2.6']
modes = [
    'ROUND_HALF_UP',     # half away from zero, C와 수학의 반올림
    'ROUND_HALF_DOWN',   # half toward zero
    'ROUND_HALF_EVEN',   # half to even, Python 기본
    'ROUND_UP', 
    'ROUND_DOWN',        
]

for mode in modes:
    getcontext().rounding = mode
    print(f"{mode:15}: ", list(map(lambda x: f"{x:2}", [int(Decimal(v).quantize(Decimal('1'))) for v in values])))

 

Python 의 decimal 모드 비교

decimal 모드 decimal 공식 의미 tie(half) 처리 규칙
(표준 용어)
예시
2.5 / -2.5
비고
ROUND_HALF_UP 소수부 = 0.5면 부호 방향,
그 외는 nearest neighbor int
half away from zero 3 / -3 C (C99)
round(),
수학 교과서
ROUND_HALF_DOWN 소수부 = 0.5면 0 방향.
그 외는 nearest neighbor int
half toward zero 2 / -2 -
ROUND_HALF_EVEN 소수부 = 0.5면 가장 가까운 짝수,
그 외는 nearest neighbor int
half to even 2 / -2 Python 내장
round()
ROUND_UP 소수부 > 0이면 항상 0에서 멀어짐(부호 방향),
소수부 = 0이면 변화 없음
away from zero
(half 개념 없음)
3 / -3 nearest neighbor 모드가 아님.
ROUND_DOWN 소수부 > 0이면 항상 0 방향,
소수부 = 0이면 변화 없음
toward zero
(half 개념 없음)
2 / -2 nearest neighbor 모드가 아님.

예제: -2.6 ~ 2.6 비교

Mode -2.6 -2.5 -2.3 -1.6 -1.5 -1.3 -0.6 -0.5 -0.3 0.3 0.5 0.6 1.3 1.5 1.6 2.3 2.5 2.6
ROUND_HALF_UP -3 -3 -2 -2 -2 -1 -1 -1 0 0 1 1 1 2 2 2 3 3
ROUND_HALF_DOWN -3 -2 -2 -2 -1 -1 -1 0 0 0 0 1 1 1 2 2 2 3
ROUND_HALF_EVEN -3 -2 -2 -2 -2 -1 -1 0 0 0 0 1 1 2 2 2 2 3
ROUND_UP -3 -3 -3 -2 -2 -2 -1 -1 -1 1 1 1 2 2 2 3 3 3
ROUND_DOWN -2 -2 -2 -1 -1 -1 0 0 0 0 0 0 1 1 1 2 2 2

 

728x90

'Python' 카테고리의 다른 글

CLI Program에서의 arguments - argparse모듈  (1) 2025.08.12
match statement-Structural Pattern Matching-match/case  (3) 2025.08.11
docstring  (3) 2025.08.07
webbrowser 모듈 사용법  (2) 2025.08.07
show Naver map-Python  (3) 2025.08.07