PGR21.com
- PGR21 관련된 질문 및 건의는 [건의 게시판]을 이용바랍니다.
- (2013년 3월 이전) 오래된 질문글은 [이전 질문 게시판]에 있습니다.
통합 규정을 준수해 주십시오. (2015.12.25.)
Date 2021/05/02 20:31:04
Name ArcanumToss
Subject [질문] 파이썬 반올림 함수 round 질문입니다.
도무지 이해가 안 되네요.
파이썬의 round 함수는 어떤 원리로 저런 값이 나오는 건가요?

print(round(1.5)) # 가까운 짝수로? 2
print(round(3.5)) # 가까운 짝수로? 4
print(round(5.5)) # 가까운 짝수로? 6
print(round(7.5)) # 가까운 짝수로? 8
print(round(9.5)) # 가까운 짝수로? 10

print(round(0.5)) # 가까운 짝수로? 0
print(round(2.5)) # 가까운 짝수로? 2
print(round(4.5)) # 가까운 짝수로? 4
print(round(6.5)) # 가까운 짝수로? 6
print(round(8.5)) # 가까운 짝수로? 8
print()

print(round(1.55)) # 가까운 짝수로? 2
print(round(3.55)) # 가까운 짝수로? 4
print(round(5.55)) # 가까운 짝수로? 6
print(round(7.55)) # 가까운 짝수로? 8
print(round(9.55)) # 가까운 짝수로? 10

print(round(0.55)) # 가까운 홀수로? 1
print(round(2.55)) # 가까운 홀수로? 3
print(round(4.55)) # 가까운 홀수로? 5
print(round(6.55)) # 가까운 홀수로? 7
print(round(8.55)) # 가까운 홀수로? 9
print()

print(round(0.55, 1)) # 그럼 이건??? 0.6
print(round(1.55, 1)) # 그럼 이건??? 1.6
print(round(8.55, 1)) # 그럼 이건??? 8.6
print(round(9.55, 1)) # 그럼 이건??? 9.6
print()
print(round(2.55, 1)) # 그럼 이건??? 2.5
print(round(3.55, 1)) # 그럼 이건??? 3.5
print(round(4.55, 1)) # 그럼 이건??? 4.5
print(round(5.55, 1)) # 그럼 이건??? 5.5
print(round(6.55, 1)) # 그럼 이건??? 6.5
print(round(7.55, 1)) # 그럼 이건??? 7.5

통합규정 1.3 이용안내 인용

"Pgr은 '명문화된 삭제규정'이 반드시 필요하지 않은 분을 환영합니다.
법 없이도 사는 사람, 남에게 상처를 주지 않으면서 같이 이야기 나눌 수 있는 분이면 좋겠습니다."
클린코더
21/05/02 20:40
수정 아이콘
파이썬에 익숙하지 않아서 저도 궁금해서 찾아보니 파이썬은 Round half to even 이라는 반올림 처리법을 따르고 있네요. 한국말로는 오사오입 이라고 하는 듯 합니다. 추가로 나무위키에 따르면 파이썬 버전마다 다른것 같습니다
"Python에서는 Microsoft Excel처럼 round 함수로 반올림을 할 수 있다. 다만, Python2에서는 사사오입법을, Python3에서는 오사오입법을 쓴다는 게 특징." https://namu.wiki/w/%EB%B0%98%EC%98%AC%EB%A6%BC 참고하세요
ArcanumToss
21/05/02 20:58
수정 아이콘
제가 올린 소스를 보면...

소숫점 이하 첫째 자리까지의 수는 가까운 짝수로 되는데
소숫점 이하 둘째 자리까지의 수는 반(정수부가 홀수면)은 가까운 짝수, 나머지 반(정수부가 짝수면)은 가까운 홀수로 바뀌고 있습니다.

그런데 소숫점 이하 둘째 자리까지의 수를 소숫점 이하 첫째 자리까지만 표현하도록 하면 규칙성이 안 보입니다... ㅠ.ㅠ



골아프니 그냥 반올림 함수를 직접 만들어서 쓰는 게 나은 듯 하네요. 흐흐

import math

def round_ori(n, decimals=0):
expoN = n * 10 ** decimals
if abs(expoN) - abs(math.floor(expoN)) < 0.5:
return math.floor(expoN) / 10 ** decimals
return math.ceil(expoN) / 10 ** decimals
클린코더
21/05/02 21:03
수정 아이콘
두번쨰 파라미터가 반올림을 한후 소숫점 자릿수인것 같은데, 기본값이 0일 겁니다. 그래서 [print(round(0.55)) # 가까운 홀수로? 1] 의 경우엔 소숫점 자릿수가 0개로 반올림 하기때문에 0.55는 0.5 보다 커서 오사오입의 대상이 아니라 그냥 바로 1로 올림하는 거일거구요.
지구사랑
21/05/02 22:51
수정 아이콘
0.55 는 논할 것이 없고 (무조건 1로 올라가는 것이 맞죠), 0 과 1 의 중간값인 0.5 를 1 로 올리느냐 0 으로 내리느냐가 문제인데,
항상 올리는 것으로 처리하면 통계적으로 + 노이즈가 더해지는 효과가 생기므로, 한 번은 올리고 한 번은 내리는 것이 합리적일 수 있습니다.
다만 부동소숫점 표현은 유효 숫자 문제가 있으므로, 0.5 가 아닌 0.05 에 대해서 0.1 을 기준으로 round() 를 하면 위의 원칙이 잘 맞지 않게 됩니다.
(0.5 는 1/2 이지만 0.05 는 이진수로 딱 떨어지지 않죠.)
X.05 가 내부적으로 X.049999999 로 표현될지 X.0500000001 로 표현될지는 X 값에 따라 달라지니까요.
ArcanumToss
21/05/03 02:10
수정 아이콘
Rorschach님의 설명과 함께 보니 님의 말씀이 무슨 말씀인지 알겠습니다.
2진수로 처리하는 문제 때문에 발생하는 문제점이로군요.
이해했습니다.
고맙습니다.
Rorschach
21/05/03 01:27
수정 아이콘
그냥 파이썬이 숫자 처리를 그렇게 해서 생기는 문제인데, 숫자를 소수점 아래 16자리 넘게 표시해보면 실제 값이 딱 떨어지지가 않아요.
위에 지구사랑님 말씀처럼 0.5 기준의 반올림은 이진수로 딱 떨어지는데 소수점이 더 내려가면 5 단위가 정확히 잘 떨어지지 않습니다.
그래서 그냥 round(a*10)/10 으로 하면 제대로 값이 나옵니다.

for i in range(20):
a = (i+0.55)
print("%20.18f"%a, round(a,1), round(a*10)/10)

이거 한 번 실행시켜 보시면 숫자가 어떻게 나오길래 저렇게 값이 나오는지 확인하실 수 있으실거예요.
ArcanumToss
21/05/03 02:15
수정 아이콘
님의 설명 덕분에 파이썬의 수치 처리 방식에 대한 이해가 생겼습니다.

round(a*10)/10 <- 요게 def round_ori() 함수의 처리 부분의 방식과 딱 동일한 원리군요!!
고맙습니다.
ArcanumToss
21/05/03 02:57
수정 아이콘
결론은 함수를 새로 만들어서 써야 하는군요.
엑셀과 똑같이 작동하는 함수를 만들었습니다.
필요하면 쓰세요.
뭐라도 답례를 드리고 싶어서요. ^^;


from math import *

def round_ori(n, decimals=0):
expoN = n * 10 ** decimals
if abs(expoN) - abs(floor(expoN)) < 0.5:
if decimals <= 0:
return int(floor(expoN) / 10 ** decimals)
return floor(expoN) / 10 ** decimals
if decimals <= 0:
return int(ceil(expoN) / 10 ** decimals)
return ceil(expoN) / 10 ** decimals
ArcanumToss
21/05/03 03:57
수정 아이콘
print("2.55 -> %.1f" % 2.55) # 2.55 -> 2.5
print("2.55 -> %s" % round(2.55, 1)) # 2.55 -> 2.5

둘 다 똑같이 나오는 것도 문제네요.
round 함수를 안 쓰고 %.1f로 해 보려 했더니만... ㅠ.ㅠ
허긴 내부적으로 처리하는 방식이 같을테니 그럴 수밖에 없겠네요.
솁첸코
21/05/03 01:37
수정 아이콘
(수정됨) https://docs.python.org/ko/3/library/functions.html#round
https://docs.python.org/ko/3/tutorial/floatingpoint.html
공식 문서에서도 주의해야될 부분으로 나오네요, 제가 쓰기보다 공식 문서 설명이 좋은 것 같아 링크 가져옵니다.

첨언하자면 파이썬에서 숫자를 좀 편하게 다루는 편이다보니 간과하기 쉬운데 부동소수점 표현법에 대한 이해도는 꽤 중요하다고 생각하는 편이라 한번 기회되시면 위 문서정도라도 정독해보시는걸 추천드립니다 이미 아시는 내용을 연관시키지 못하신걸수도 있지만...
ArcanumToss
21/05/03 02:53
수정 아이콘
그러고 보니 공식 문서에 주의하라고 나오네요.
파이썬... 묘하네요. 흐흐
21/05/03 06:58
수정 아이콘
스택오버플로우 찾아보니 decimal 모듈 쓰는게 제일 좋다고 하네요.

from decimal import Decimal, ROUND_UP

Decimal(str(16.2)).quantize(Decimal('.01'), rounding=ROUND_UP)
=
16.20

https://stackoverflow.com/questions/56820/round-doesnt-seem-to-be-rounding-properly
ArcanumToss
21/05/03 16:24
수정 아이콘
크크크 파이썬의 반올림 문제 때문에 다들 골머리가 아팠었나보네요.
다양한 방법이 올라와 있는 걸 보니...
round(16.2, -1)처럼 1의 자리에서 반올림하는 게 안 되는 걸 빼면 아주 좋네요.
고맙습니다. ^^
목록 삭게로! 맨위로
번호 제목 이름 날짜 조회
175742 [질문] 가성비 좋은 휴대폰 있을까요? [6] Rays1122 24/04/12 1122
175741 [질문] 자전거 처음인데 잘 타는법 있을까요? [17] 류크1084 24/04/12 1084
175740 [질문] 특정 usb를 꽂았다 뺀 이후로 pc에서 덜그덕 소리가 납니다;; [4] 하나765 24/04/12 765
175739 [질문] 여름철에 햇빛 잘 막으면서 무난하게 쓰고 다닐만한 모자 추천 부탁드립니다 [5] 파르셀638 24/04/12 638
175738 [질문] 음주 교통사고 질문이 있습니다. [2] shadowtaki1227 24/04/12 1227
175737 [질문] (If) 삼국지에서 위나라가 진나라에 정권 안 뺏기고 통일 했으면? [6] pecotek1277 24/04/12 1277
175736 [삭제예정] 결혼준비 갈등 ..조언부탁드립니다. [43] 삭제됨2749 24/04/12 2749
175735 [질문] 웹툰 추천 좀 부탁드립니다. [16] 2501232 24/04/12 1232
175733 [질문] 주린이 질문입니다..(토스증권, 미국주식) [8] 속보1377 24/04/12 1377
175732 [질문] 혹시 예가체프 더치커피 파는 카페있을까요? [4] 스물다섯대째뺨1138 24/04/12 1138
175731 [질문] TV용으로 돌비가 지원되는 가성비 무선 헤드폰 추천 부탁드립니다. [2] 깐쇼새우1499 24/04/12 1499
175730 [질문] [도와주세요]소리만 듣고 무슨 폰게임인지 찾아내야합니다!! [6] 불대가리2240 24/04/11 2240
175729 [질문] 머리 편하게 식힐게 뭐가 있을까요? [22] 항정살2866 24/04/11 2866
175728 [질문] 초등학교 1학년 로블록스?? 괜찮을까요?? [13] 애기찌와2271 24/04/11 2271
175727 [질문] 버스킹을 립싱크로 하는 건 무슨 이유일까요? [5] 짐바르도2581 24/04/11 2581
175726 [질문] 스타크래프트1 맵이 실행이 되지 않습니다. [3] 버디홀리930 24/04/11 930
175725 [질문] 윈도우 업데이트 하고나서 컴퓨터 부팅이 안됩니다 [5] 흑마법사1504 24/04/11 1504
175723 [질문] 엑셀 질문 드립니다. 각 셀에 지역별 인원 수 뽑는법 [16] 본좌1320 24/04/11 1320
175722 [질문] 스타크래프트1 실행이 안됩니다 [5] S.hermit1217 24/04/11 1217
175721 [삭제예정] 전기차 주차구역에 주차 후 신고당해서 과태료를 물게 된 사람 관련해서 [21] 삭제됨2563 24/04/11 2563
175720 [질문] 파이썬 독학 어려울까요? [8] Alfine1793 24/04/11 1793
175719 [질문] 턴키 인테리어 질문 [5] 잠이오냐지금963 24/04/11 963
175718 [질문] 엣지에서 코파일럿 사용 질문 [8] 아테스형1223 24/04/11 1223
목록 이전 다음
댓글

+ : 최근 1시간내에 달린 댓글
+ : 최근 2시간내에 달린 댓글
맨 위로