Using Python Fractions
Pythonfrom fractions import Fraction # Create fractions f1 = Fraction(1, 3) # 1/3 f2 = Fraction('3.14') # 157/50 (from decimal string) f3 = Fraction('22/7') # from string ratio f4 = Fraction(0.5) # 1/2 (exact binary float conversion) f5 = Fraction(Decimal('1.1')) # from Decimal, exact # Arithmetic stays exact result = Fraction(1, 3) + Fraction(1, 6) # Fraction(1, 2) print(result) # 1/2
-
Choose the right constructor input
Fraction(numerator, denominator)— two integers, auto-reduced via GCDFraction(other_fraction)— copyFraction(float)— exact value of the float (not the "nice" decimal you'd expect)Fraction(decimal.Decimal)— exact value, preferred over float for decimal-like inputFraction(string)— parses"3/4","-3/4","1.5","1.5e3", with optional whitespace and underscores in numbers
-
Use arithmetic operators normally —
+ - * / **all returnFraction(or complex/float when mixed with those types). -
Access components when needed:
Pythonf = Fraction(6, 8) # auto-reduces to Fraction(3, 4) f.numerator # 3 f.denominator # 4 -
Convert to/from other numeric types:
Pythonfloat(Fraction(1, 3)) # 0.3333333333333333 Fraction(1, 3).limit_denominator(10) # Fraction(1, 3) — best approx with denom <= 10 f.as_integer_ratio() # (3, 4) -
Round, floor, ceil — Fractions support
round(),math.floor(),math.ceil(),math.trunc()natively.
Example 1: Avoiding float imprecision Input:
Python0.1 + 0.2 == 0.3 # False due to float rounding Fraction('0.1') + Fraction('0.2') == Fraction('0.3')
Output: True — exact decimal-string parsing avoids binary float error.
Example 2: Approximating an irrational-ish float as a simple fraction Input:
Pythonimport math Fraction(math.pi).limit_denominator(1000)
Output: Fraction(355, 113) — best rational approximation with denominator ≤ 1000.
Example 3: Parsing user input safely Input:
PythonFraction(" -3/4 ") Fraction("1_000/2_000")
Output: Fraction(-3, 4), Fraction(1, 2)
Example 4: GCD reduction happens automatically
Input: Fraction(10, 4)
Output: Fraction(5, 2)
- Always construct
Fractionfrom a string or Decimal when the source is a decimal literal you typed (e.g.,Fraction('1.1')), neverFraction(1.1), unless you specifically want the float's exact (ugly) binary value. - Use
.limit_denominator(max_denominator)to get human-friendly approximations, e.g. for displaying measurements. - Fractions are hashable and immutable — safe to use as dict keys or in sets.
- Comparisons (
<,==, etc.) work exactly againstint,float,Decimal, and otherFractions. - For repeated heavy numeric computation, convert to
floatorDecimalat the boundary —Fractionarithmetic is exact but slower due to GCD reduction on every operation.
Fraction(0.1)is NOTFraction(1, 10)— it's the exact (ugly) binary representation of the float0.1, e.g.Fraction(3602879701896397, 36028797018963968). UseFraction('0.1')instead.- Don't assume
numerator/denominatorreflect what you passed in — they're always stored in lowest terms with a positive denominator. - Division by zero raises
ZeroDivisionError, same as normal Python numbers. - Mixing
Fractionwithfloatin arithmetic returns afloat(losing exactness) — keep operations withinFraction/Decimal/intto stay exact.