CodeGym /행동 /Python SELF KO /실수 작업하기

실수 작업하기

Python SELF KO
레벨 5 , 레슨 4
사용 가능

4.1 실수 반올림

실수는 영어로 floating 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 타입 내부에 두 숫자가 저장돼 — 234567898. 빨간색은 "유효 숫자" (mantissa)를, 녹색은 지수를 나타내.

이런 접근 방식 덕분에 매우 큰 숫자와 작은 숫자 모두를 저장할 수 있어. 하지만 숫자의 크기는 8바이트 (64비트)로 제한되어 있고, 일부 비트는 지수 (그리고 숫자의 부호와 지수의 부호)를 저장하는 데 사용돼, mantissa의 최대 길이는 15자리로 제한돼.

이건 아주 간단한 부동 소수점 숫자의 구조 설명이고, 더 자세한 건 구글에서 검색할 수 있어.

4.3 실수 작업 시 정밀도 손실

실수로 작업할 때는 항상 부정확함을 염두에 두어야 해. 반올림 오류, 변환 오류로 인한 오류가 항상 있을 거야. 예를 들어, 십진수 시스템에서 2진수 시스템으로 변환할 때, 그리고 무엇보다 너무 다른 크기의 숫자를 더하거나 뺄 때 정밀도 손실이 가장 자주 발생해.

마지막 경우가 프로그래밍 초보자들에게 가장 예상치 못한 상황이야.

만약 숫자 109에서 1/109를 빼면, 다시 109를 얻게 돼.

너무 다른 크기의 숫자 빼기 설명

1000000000.000000000
-     0.000000001
1000000000.000000000
                            
두 번째 숫자는 너무 작아서 유효 숫자 부문이 무시돼 (회색으로 표시돼). 주황색은 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("다르지")
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION