05. 다섯 번째 수업: 실수의 대소 비교 (Ordering Reals)
실수(Real Numbers)의 세계, 즉 수직선이 거대한 하나의 선으로 완성되었다면, 그 선 위에 있는 모든 숫자들은 “누가 누구보다 큰가?”를 일렬로 세워 비교할 수 있어야 합니다.
1. 수직선 위의 절대 규칙
수학에서 실수의 크기를 비교하는 절대 규칙은 단 하나입니다. “수직선에서 오른쪽에 있는 숫자가 왼쪽보다 무조건 크다.”
- 양수 > 0 > 음수
- 두 숫자가 양수일 때: 절댓값(0에서 떨어진 오프셋 거리)이 큰 숫자가 큰 숫자. ($5 > 3$)
- 두 숫자가 음수일 때: 절댓값이 큰 쪽(왼쪽으로 더 깊이 들어간 쪽)이 더 작은 숫자. ($-5 < -3$)
2. 루트($\sqrt{\quad}$)가 씌워진 숫자들의 크기 비교
만약 서로 다른 두 개의 루트값, $\sqrt{2}$ 와 $\sqrt{3}$ 중 누가 더 큰지 비교하려면 어떻게 할까요? 이는 넓이가 2인 정사각형의 한 변의 길이와, 넓이가 3인 정사각형의 변의 길이를 비교하는 것과 똑같습니다. 넓이가 더 큰 피자의 모서리 길이가 당연히 더 길겠죠?
따라서 안에 들어있는 알맹이가 클수록 루트 씌운 값도 더 큽니다. $a < b$ 이면 $\sqrt{a} < \sqrt{b}$ 이다. (단, $a$, $b$는 양수)
3. 정수와 루트의 이종 격투기 비교
학생들을 가장 힘들게 하는 것은 서로 태생이 다른 정수와 무리수를 비교하는 문제입니다. 예를 들어, $3$ 과 $\sqrt{10}$ 중 누가 더 클까요?
이 둘을 비교하려면 무기를 통일해야 합니다. 정수 $3$ 을 강제로 루트($\sqrt{\quad}$) 감옥 안에 집어넣어 동등한 조건에서 스파링을 시키는 것입니다. 정수가 루트 안에 들어갈 때는 자신의 몸을 제곱($x^2$)해서 들어갑니다.
- $3 = \sqrt{3^2} = \sqrt{9}$
- 이제 $\sqrt{9}$ 와 $\sqrt{10}$ 을 비교합니다.
- 알맹이가 $10$ 이 더 크므로, $\sqrt{10} > \sqrt{9}$ 입니다.
- 결론: $\sqrt{10} > 3$
4. 파이썬과 소수점 비교의 함정
수학 시험지에서는 정수에 루트를 씌우는 우회법칙을 쓰지만, 소수점 다루기에 특화된 파이썬 프로그래머들은 그냥 소수점으로 변환한 뒤 부등호 열방향 하나로 승리자를 가려냅니다.
하지만, 아주 미세한 차이를 지닌 두 실수를 컴퓨터로 비교할 때는 끔찍한 사고가 발생할 수 있습니다!
# [Python] 실수의 크기 비교와 `math.isclose()` 의 안전성
import math
# 1. 자연스러운 대소 비교 (루트 10 과 3)
num1 = math.sqrt(10) # 약 3.162...
num2 = 3
if num1 > num2:
print(f"-> {num1} 가 {num2} 보다 크다! (sqrt(10) 윈!)")
# 2. 프로그래머들의 무덤: 소수점 연산의 미세 오차 비교
# 0.1 + 0.2 는 수학적으로 완벽히 0.3 이지만, 컴퓨터의 Float 한계에서는 0.30000000000000004 가 됩니다.
float_math = 0.1 + 0.2
perfect_real = 0.3
# == 부등호로 미친 오차를 직접 비교하면 수학 엔진이 박살납니다.
if float_math == perfect_real:
print("-> 0.1+0.2 는 0.3 과 같다!")
else:
print(f"-> 에러! 0.1+0.2({float_math}) 는 0.3 과 다르다고 판정됨!!!")
# 3. 해법: math.isclose() (실수 전용 안전 비교 함수)
# "두 실수가 허용 가능한 아주 미세한 오차 범위 내에 있으면 같다고 쳐주자"
if math.isclose(float_math, perfect_real):
print("-> 휴! math.isclose() 를 쓰니 0.1+0.2 와 0.3 가 같다고 안전하게 판정되었습니다.")
[실행 결과]
-> 3.1622776601683795 가 3 보다 크다! (sqrt(10) 윈!)
-> 에러! 0.1+0.2(0.30000000000000004) 는 0.3 과 다르다고 판정됨!!!
-> 휴! math.isclose() 를 쓰니 0.1+0.2 와 0.3 가 같다고 안전하게 판정되었습니다.
무리수나 소수점 연산을 다루는 파이썬 코드를 짤 때 == 기호(절대 일치)를 사용하는 것은 시한폭탄과 다름없습니다. 컴퓨터의 64비트 메모리 한계로 인해 무조건 끝자리에 오차가 붙기 때문이죠. 항상 math.isclose() 와 같은 실수 전용 포용 함수를 사용하여 비교의 안전성을 확보해야 합니다.