06. 여섯 번째 수업: 유한소수의 비밀 (Terminating Decimals)

우리는 여태까지 유리수를 ‘분수’ 형태로만 다루었습니다. 하지만 과학이나 실생활 계산에서는 종종 분수를 소수점 형태(예: $0.5$, $0.25$)로 변환해야 할 때가 많습니다.


1. 10의 거듭제곱과 소수의 관계

소수라는 녀석은 사실 분모가 10, 100, 1000… 인 특별한 분수들의 또 다른 이름표에 불과합니다.

  • $0.1 = \frac{1}{10}$
  • $0.25 = \frac{25}{100}$
  • $3.14 = \frac{314}{100}$

이렇게 나누어 떨어져서 깔끔하게 숫자가 끝나는 소수를 유한소수(Terminating Decimal)라고 부릅니다. 그렇다면 세상의 모든 분수는 유한소수로 깔끔하게 변신할 수 있을까요?

2. 비밀은 2와 5에게 있다!

어떤 분수가 깔끔하게 떨어지는 유한소수가 될 수 있는지의 여부는 순전히 “분모”에 달려있습니다. 소수를 만들려면 분모가 결국 $10, 100, 1000$ 등으로 변해야 합니다.

10을 자세히 들여다볼까요? $10 = 2 \times 5$ 입니다. 100은? $100 = 10 \times 10 = (2 \times 5) \times (2 \times 5) = 2^2 \times 5^2$ 입니다.

즉, $10$의 거듭제곱들은 모두 오직 $2$와 $5$라는 소인수로만 이루어져 있습니다. 따라서 어떤 분수를 기약분수(더 이상 약분되지 않는 가장 간단한 상태)로 만들었을 때, 분모의 소인수가 $2$나 $5$뿐이라면, 그 분수는 무조건 10, 100, 1000… 꼴로 확장될 수 있고, 결국 깔끔한 유한소수로 딱 떨어지게 됩니다.

  • $\frac{1}{8}$ $\rightarrow$ $8 = 2 \times 2 \times 2$ ($2$뿐이네!) $\rightarrow$ 위아래에 $5^3(125)$을 곱하면 $\frac{125}{1000} = 0.125$ (유한소수)
  • $\frac{7}{20}$ $\rightarrow$ $20 = 2^2 \times 5$ ($2$와 $5$뿐이네!) $\rightarrow$ 위아래에 $5$를 곱하면 $\frac{35}{100} = 0.35$ (유한소수)
  • $\frac{1}{3}$ $\rightarrow$ 분모가 $3$이다. 아무리 용을 써도 $10$이나 $100$을 만들 수 없다! $\rightarrow$ 유한소수 불가능!

3. 파이썬으로 유한소수 여부 탐지하기

이 $2$와 $5$의 법칙을 컴퓨터 코드(파이썬)로 짜보면 어떻게 될까요? 분모의 인수가 $2$와 $5$만 남을 때까지 계속 빨아들이듯 나누어 보면 됩니다. 나누고 남은 찌꺼기가 $1$이 아니면, 불순물(3, 7 등)이 섞여 있다는 뜻이므로 유한소수가 될 수 없습니다.

# [Python] 주어진 분수가 깔끔하게 끝나는 유한소수인지 감별하는 프로그램
import math

def is_terminating_decimal(numerator, denominator):
    # 1. 먼저 가장 날씬한 기약분수로 압축한다.
    gcd = math.gcd(numerator, denominator)
    simp_den = denominator // gcd
    
    # 2. 분모에서 소인수 '2'들을 모조리 걸러낸다.
    while simp_den % 2 == 0:
        simp_den //= 2
        
    # 3. 분모에서 소인수 '5'들을 모조리 걸러낸다.
    while simp_den % 5 == 0:
        simp_den //= 5
        
    # 쳐낼 것을 다 쳐냈는데 1로 완전히 깔끔해졌다면? 오직 2와 5로만 이루어졌다는 뜻!
    if simp_den == 1:
        return True
    else:
        # 다른 숫자가 남아있다면(예: 3, 7 등) 유한소수 불가능!
        return False

# 테스트
fractions = [(3, 8), (7, 20), (1, 3), (9, 15)]

for num, den in fractions:
    is_term = is_terminating_decimal(num, den)
    state = "유한소수!" if is_term else "무한소수(순환소수)..."
    result = num / den
    print(f"분수 {num}/{den} -> 검사 결과: {state} (실제 값: {result})")

[실행 결과]

분수 3/8 -> 검사 결과: 유한소수! (실제 값: 0.375)
분수 7/20 -> 검사 결과: 유한소수! (실제 값: 0.35)
분수 1/3 -> 검사 결과: 무한소수(순환소수)... (실제 값: 0.3333333333333333)
분수 9/15 -> 검사 결과: 유한소수! (실제 값: 0.6)

잠깐, $9/15$는 왜 유한소수일까요? $15 = 3 \times 5$라서 불순물 $3$이 있는데요? 정답은 “약분”에 있습니다! $\frac{9}{15}$를 기약분수로 만들면 분자의 $9$가 $3$을 죽여주어 $\frac{3}{5}$이 되기 때문입니다. 그래서 파이썬 코드에도 1번에 math.gcd를 통해 기약분수로 만드는 로직이 철저하게 포함되어 있는 것입니다.

서브목차