4.1 실수 반올림
실수는 영어로
float
ing point number라고 불려: 미국에서는 정수와 소수 부문을 점으로 나누어. 그래서 float
라는 이름이 생긴 거야.
이미 다뤄봤지만, 실수(float)를 정수(int)로 변환할 때, 언제나 숫자를 내림 처리해 — 소수 부문은 그냥 버려지지. 근데 때로는 소수를 가까운 정수로 반올림하고 싶을 때가 있을 거야. 이런 경우 어떻게 해야 할까?
그럴 때 Python에서는 기본 함수
round()
가 있어. 이건 math 라이브러리가 만들어지기 전에 생긴 거라, 그 안에 들어있지 않아. 내림과 올림을 위한 함수들은 math 라이브러리에 있어.
round()
함수는 숫자를 가장 가까운 정수로 반올림해:
round(실수)
이 함수는 전달된 실수에서 더 가까운 정수를 반환해. 중요한 건, 만약 소수 부문이 0.5라면, round()
함수는 가장 가까운 짝수 정수를 반환하는 "은행가 반올림" 방법을 사용해. 예를 들어:
예제:
명령어 | 결과 |
---|---|
x = round(4.1) | 4 |
x = round(4.5) | 4 |
x = round(4.9) | 5 |
x = round(5.5) | 6 |
math.ceil()
함수는 숫자를 올림하여 정수로 만들어, 예제:
명령어 | 결과 |
---|---|
x = math.ceil(4.1) | 5 |
x = math.ceil(4.5) | 5 |
x = math.ceil(4.9) | 5 |
math.floor()
함수는 숫자를 내림하여 정수로 만들어, 예제:
명령어 | 결과 |
---|---|
x = math.floor(4.1) | 4 |
x = math.floor(4.5) | 4 |
x = math.floor(4.9) | 4 |
숫자를 내림하여 정수로 만들 때는 타입 변환 함수 int()
를 사용하는 것이 더 간단해:
명령어 | 결과 |
---|---|
x = int(4.9) | 4 |
명령어들이 기억하기 어렵다면, 영어 수업이 도움이 될 거야:
math
— 수학round
— 원/반올림ceiling
— 천장floor
— 바닥
4.2 부동 소수점 숫자의 구조
Python에서 float
타입은 -1.7*10308에서 +1.7*10308까지 값을 저장할 수 있어. 이 엄청난 값의 범위는 float
타입이 정수 타입과는 전혀 다른 구조를 가지고 있기 때문이야. 각 float
타입 변수는 두 숫자를 포함하고 있어: 첫 번째는 "mantissa", 두 번째는 "exponent"라 불려.
예를 들어, 123456789라는 숫자가 있고, 이를 float
형 변수에 저장했어. 그럼 숫자는 1.23456789*108로 변환돼, float
타입 내부에 두 숫자가 저장돼 — 23456789와 8. 빨간색은 "유효 숫자" (mantissa)를, 녹색은 지수를 나타내.
이런 접근 방식 덕분에 매우 큰 숫자와 작은 숫자 모두를 저장할 수 있어. 하지만 숫자의 크기는 8바이트 (64비트)로 제한되어 있고, 일부 비트는 지수 (그리고 숫자의 부호와 지수의 부호)를 저장하는 데 사용돼, mantissa의 최대 길이는 15자리로 제한돼.
이건 아주 간단한 부동 소수점 숫자의 구조 설명이고, 더 자세한 건 구글에서 검색할 수 있어.
4.3 실수 작업 시 정밀도 손실
실수로 작업할 때는 항상 부정확함을 염두에 두어야 해. 반올림 오류, 변환 오류
로 인한 오류가 항상 있을 거야. 예를 들어, 십진수 시스템에서 2진수 시스템으로 변환할 때, 그리고 무엇보다 너무 다른 크기의 숫자를 더하거나 뺄 때 정밀도 손실
이 가장 자주 발생해.
마지막 경우가 프로그래밍 초보자들에게 가장 예상치 못한 상황이야.
만약 숫자 109에서 1/109를 빼면, 다시 109를 얻게 돼.
너무 다른 크기의 숫자 빼기 | 설명 |
---|---|
|
두 번째 숫자는 너무 작아서 유효 숫자 부문이 무시돼 (회색으로 표시돼). 주황색은 15개의 유효 숫자를 나타내. |
여기서 무엇을 말할 수 있냐면, 프로그래밍은 수학이 아니야.
4.4 실수 비교의 위험성
실수를 비교할 때 또 다른 위험이 도사리고 있어. 실수로 작업할 때 반올림 오류가 누적될 수 있어서, 정작 실수가 같아야 하는 상황에서도 다를 수 있고, 반대로 달라야 하는 상황에서도 같을 수 있어.
예제:
명령어 | 설명 |
---|---|
a = 1000000000.0 b = 0.000000001 c = a – b |
a 변수는 1000000000.0 값을 가질 거야 c 변수는 1000000000.0 값을 가질 거야 (b 변수의 숫자가 너무 작아) |
위 예제에서 a와 c는 같으면 안 되지만, 실제로 같아.
또 다른 예를 보자:
명령어 | 설명 |
---|---|
a = 1.00000000000000001 b = 1.00000000000000002 |
a 변수는 1.0 값을 가질 거야 b 변수는 1.0 값을 가질 거야 |
실제로 실수를 비교할 때는 이렇게 해:
아주 작은 값을 잡아서, 숫자들의 차이 (절대값)이 그 작은 값보다 작으면, 동일하다고 간주해. 예시:
a = 0.00000000012
b = 0.000000000011
if abs(a - b) < 0.00001:
print("같아")
else:
print("다르지")
GO TO FULL VERSION