Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

Python Rational Numbers: โมดูล fractions สำหรับเศษส่วนแม่นยำ

เลขตรรกยะ (Rational Numbers) คือเลขที่เขียนในรูปเศษส่วน p/q ได้ โมดูล fractions ใน Python standard library ให้คลาส Fraction สำหรับคำนวณเศษส่วนอย่างแม่นยำ (ไม่มี floating-point errors)

สร้าง Fraction Object

from fractions import Fraction

# Fraction(numerator, denominator)
f1 = Fraction(2, 5)      # 2/5
f2 = Fraction(6, 15)     # 2/5 (ลดรูปอัตโนมัติ)
f3 = Fraction(10, 1)     # 10
f4 = Fraction(10)        # 10/1 (denominator default = 1)

# จาก String
f5 = Fraction('5')       # 5/1
f6 = Fraction('4/7')     # 4/7
f7 = Fraction('0.25')    # 1/4
f8 = Fraction('1.23E4')  # 12300/1

# จาก Float (อาจไม่แม่นยำเพราะ binary representation)
f9 = Fraction(2.1)       # 4728779608739021/2251799813685248 😱

# จาก Decimal (แม่นยำ!)
from decimal import Decimal
f10 = Fraction(Decimal('2.1'))  # 21/10 ✅

คุณสมบัติของ Fraction

  • ลดรูปอัตโนมัติ: 6/15 → 2/5
  • Denominator ≠ 0: Fraction(1, 0) → ZeroDivisionError
  • Sign normalization: ตัวลบอยู่ numerator เสมอ

เข้าถึง Numerator และ Denominator

f = Fraction(2, 3)
print(f.numerator)    # 2
print(f.denominator)  # 3

Arithmetic Operations (คำนวณได้ทุกอย่าง)

a = Fraction(2, 3)
b = Fraction(1, 2)

print(a + b)  # 7/6
print(a - b)  # 1/6
print(a * b)  # 1/3
print(a / b)  # 4/3
print(a ** 2) # 4/9 (power)

# กับ int/float
print(a + 1)      # 5/3
print(a * 0.5)    # 0.333... (คืน float)
print(a + Fraction(1, 2))  # 7/6 (คืน Fraction)

เมธอดพิเศษ

1. floor() และ ceil()

f = Fraction(355, 113)  # ≈ 3.14159 (π approximation)
print(f.__floor__())  # 3
print(f.__ceil__())   # 4

# หรือใช้ math module
import math
print(math.floor(f))  # 3
print(math.ceil(f))   # 4

2. limit_denominator(max_denominator)

หาเศษส่วนที่ใกล้เคียงที่สุด แต่ denominator ≤ ค่าที่กำหนด

# π ≈ 3.14159
print(Fraction('3.14159').limit_denominator(100))   # 311/99
print(Fraction('3.14159').limit_denominator(1000))  # 355/113

# e ≈ 2.71828
print(Fraction('2.71828').limit_denominator(400))   # 1071/394

3. as_integer_ratio()

f = Fraction(7, 3)
print(f.as_integer_ratio())  # (7, 3)

การเปรียบเทียบ (Comparison)

print(Fraction(1, 2) < Fraction(2, 3))   # True
print(Fraction(1, 2) == Fraction(2, 4))  # True
print(Fraction(1, 2) > 0.4)              # True

ตัวอย่างประยุกต์ใช้

คำนวณค่า π ด้วย Infinite Series (Leibniz formula)

from fractions import Fraction

def compute_pi_leibniz(n_terms):
    """π/4 = 1 - 1/3 + 1/5 - 1/7 + 1/9 - ..."""
    total = Fraction(0, 1)
    for k in range(n_terms):
        term = Fraction(1, 2*k + 1)
        if k % 2 == 0:
            total += term
        else:
            total -= term
    return total * 4

# ทดสอบ
for n in [10, 100, 1000, 10000]:
    pi_approx = compute_pi_leibniz(n)
    print(f"n={n}: {pi_approx} = {float(pi_approx)}")

Exact Rational Arithmetic ใน Financial Calculations

from fractions import Fraction

# คำนวณดอกเบี้ยทบต้นอย่างแม่นยำ
principal = Fraction(10000)      # 10,000 บาท
rate = Fraction(5, 100)          # 5% = 5/100
years = 10

amount = principal * (1 + rate) ** years
print(f"Amount: {amount}")       # เศษส่วนแม่นยำ
print(f"Amount: {float(amount):.2f}")  # แปลงเป็น float เพื่อแสดง

Fraction vs Float vs Decimal

ประเภท ความแม่นยำ Performance Use Case
Fractionแม่นยำ 100% (Exact)ช้ากว่าMath, Science, Financial (ต้องการ exact)
floatประมาณ (IEEE 754)เร็วที่สุด (Hardware)General purpose, Graphics, ML
Decimalแม่นยำ (Configurable precision)ปานกลางFinancial, Accounting, Currency

สรุป

  • Fraction ให้ rational arithmetic ที่แม่นยำสมบูรณ์
  • ลดรูปอัตโนมัติ, รองรับ string, Decimal, int
  • หลีกเลี่ยง float เพื่อความแม่นยำ → ใช้ Fraction หรือ Decimal
  • มี limit_denominator() สำหรับหา approximation ที่ดี
  • เหมาะสำหรับ symbolic math, financial calculations, education