Decimal simplification
Fraction conversion
Mathematical algorithms
Number theory
Math tutorial

Algorithm for simplifying decimal to fractions

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Converting decimals to simplified fractions is a common task in calculators, symbolic tools, finance utilities, and educational software. The process is straightforward for terminating decimals and slightly more involved for repeating decimals. A robust algorithm should identify decimal type, construct the fraction, and reduce it with greatest common divisor logic.

Core Rule for Terminating Decimals

If a decimal has a finite number of digits after the point, you can convert it directly:

  1. count decimal digits
  2. remove decimal point to get numerator candidate
  3. use 10^n as denominator where n is digit count
  4. divide numerator and denominator by gcd

Example for 0.75:

  • numerator candidate is 75
  • denominator is 100
  • 'gcd(75, 100) = 25'
  • result is 3/4

This method is deterministic and fast.

Python Implementation for Terminating Decimals

Use string parsing to avoid floating-point rounding surprises.

python
1from math import gcd
2
3
4def terminating_decimal_to_fraction(s: str):
5    sign = -1 if s.startswith("-") else 1
6    s = s.lstrip("+-")
7
8    if "." not in s:
9        return sign * int(s), 1
10
11    whole, frac = s.split(".")
12    digits = len(frac)
13    numerator = int(whole + frac)
14    denominator = 10 ** digits
15
16    g = gcd(abs(numerator), denominator)
17    return sign * (numerator // g), denominator // g
18
19
20print(terminating_decimal_to_fraction("0.75"))
21print(terminating_decimal_to_fraction("-12.125"))

This avoids binary float artifacts and gives exact rational output for decimal strings.

Repeating Decimal Conversion

For repeating decimals, use algebraic subtraction.

Suppose value is x = 0.1(6) where repeating block is 6.

  • non-repeating length is 1
  • repeating length is 1

Formula approach:

  • '10^(a+b) * x - 10^a * x = repeating_integer - prefix_integer'

Where:

  • 'a is non-repeating digit count'
  • 'b is repeating block length'

Then simplify resulting fraction by gcd.

Python Function for Repeating Decimals

Represent repeating decimals with two parts: prefix and repetend.

python
1from math import gcd
2
3
4def repeating_decimal_to_fraction(int_part: str, non_rep: str, rep: str):
5    # Example inputs for 12.34(56): int_part="12", non_rep="34", rep="56"
6    a = len(non_rep)
7    b = len(rep)
8
9    left = int(int_part + non_rep + rep)
10    right = int(int_part + non_rep) if non_rep else int(int_part)
11
12    numerator = left - right
13    denominator = (10 ** (a + b)) - (10 ** a)
14
15    whole_offset = int(int_part) * denominator
16    numerator += whole_offset
17
18    g = gcd(abs(numerator), denominator)
19    return numerator // g, denominator // g
20
21
22print(repeating_decimal_to_fraction("0", "1", "6"))
23print(repeating_decimal_to_fraction("2", "", "3"))

This yields exact rational forms for recurring patterns.

Use Continued Fractions for Approximation

When input is an imprecise floating number, exact conversion may not be possible or desired. In that case, use continued fractions to find the best approximation under a denominator limit.

python
1from fractions import Fraction
2
3
4def approximate_fraction(x: float, max_den: int = 10000):
5    f = Fraction(x).limit_denominator(max_den)
6    return f.numerator, f.denominator
7
8
9print(approximate_fraction(3.1415926535, 1000))
10print(approximate_fraction(0.3333333333, 1000))

This is practical for measurement data and noisy numeric input.

End-to-End Strategy in Real Software

A production converter usually follows this sequence:

  1. detect whether input is exact decimal string, repeating form, or float
  2. pick exact conversion path when possible
  3. apply gcd simplification
  4. normalize sign to numerator
  5. optionally return mixed number format for display

Keep internal representation as numerator and denominator integers for predictable math behavior.

Validation Tests You Should Keep

Key tests:

  • '0.5 -> 1/2'
  • '2.0 -> 2/1'
  • '-1.25 -> -5/4'
  • repeating 0.(3) -> 1/3
  • repeating 12.34(56) expected exact fraction

These tests protect against parsing regressions and sign mistakes.

Common Pitfalls

  • Parsing through binary float first and losing exact decimal precision.
  • Forgetting to simplify fraction by greatest common divisor.
  • Mishandling sign placement between numerator and denominator.
  • Mixing exact conversion and approximation logic without clear API behavior.
  • Ignoring repeating-decimal input formats in user-facing tools.

Summary

  • Terminating decimals convert directly using base-ten denominator logic.
  • Repeating decimals require algebraic subtraction method for exact fractions.
  • String-based parsing is safer than float-first conversion for exactness.
  • Continued-fraction style approximation is useful for noisy float inputs.
  • Always normalize and simplify output for stable downstream computation.

Course illustration
Course illustration

All Rights Reserved.