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가 줄어드는 장점이 있음. - 금융과 통계에서 보다 유리함.

참고
- Java는
Math.round()는 half toward positive infinity 로 고정 동작이나,BigDecimal로 여러 모드(예:HALF_UP,HALF_EVEN,HALF_DOWN,UP,DOWN등) 지정 가능.
- Python은
- 내장
round()는 half to even 고정 동작이나, decimal.Decimal과getcontext().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 |
