What Is a Rational Number?
A rational number is any number that can be expressed as a fraction of two integers, where the numerator is a whole number and the denominator is a non-zero integer. The decimal form of a rational number either ends (terminates) or repeats infinitely. [1, 2, 3, 4]
Key Characteristics and Forms
Rational numbers encompass a wide variety of numbers, which can always be categorized into these four main forms:
- Integers: All whole numbers, both positive and negative, are rational because they can be written as a fraction over 1 (e.g., 5 = 5/1, -3 = -3/1).
- Fractions: Any standard or mixed fraction where the top and bottom are integers (with a denominator not equal to 0) is rational (e.g., 3/4, 2 1/2).
- Terminating Decimals: Decimals that eventually stop are rational because they can be converted into fractions (e.g., 0.75 = 3/4).
- Repeating Decimals: Decimals that go on forever in a predictable, repeating pattern are rational and can be converted into fractions (e.g., 0.333... = 1/3). [3, 4, 6]
Non-Examples (Irrational Numbers)
If a number cannot be written as a fraction, and its decimal portion neither terminates nor repeats, it is considered irrational.
- Examples: π (Pi), the square root of a non-perfect square (e.g., √2), or Euler's number (e). [1, 2, 4, 6, 7]
References
- Wikipedia: Rational number
- YouTube: What is a rational number
- Mathnasium: What is a rational number
- Math is Fun: Rational Numbers
- YouTube Shorts: Rational numbers
- Mathnasium: Rational number (term)
- Mometrix: Rational Numbers
How the Code Works
The notebook below converts a floating-point number into an exact fraction, and shows why the obvious approach can be surprising. It uses Python's built-in fractions.Fraction together with SymPy's Rational and nsimplify.
- Imports:
from fractions import Fractionandfrom sympy import Rational, nsimplifybring in both the standard-library fraction type and the symbolic-math tools. - Fraction(1.1) and Fraction.from_float(1.1): these return the exact value the computer actually stores for 1.1. Because 1.1 cannot be represented exactly in binary floating point, the result is a long, unexpected fraction rather than 11/10.
- Rational(1.1): SymPy's
Rationalapplied to a float behaves the same way, reflecting the exact binary value of the float. - nsimplify(1.1):
nsimplifyworks backwards from the float to find the simple rational a human most likely meant, recovering 11/10. - to_frational(x): a small helper that prints both
Fraction(x)andnsimplify(x)side by side, so you can compare the literal floating-point fraction against the cleaned-up rational for any input.
The takeaway: converting a float straight to a fraction preserves the floating-point rounding error, while nsimplify recovers the intended simple fraction.
from fractions import Fraction
from sympy import Rational, nsimplify
Fraction.from_float(1.1)
Fraction(2476979795053773, 2251799813685248)
Fraction(1.1)
Fraction(2476979795053773, 2251799813685248)
Rational(1.1)
nsimplify(1.1)
def to_frational(x):
print(Fraction(x))
print(nsimplify(x))
print()
vals = [0.0,
1.2879011017187576,
2.5905203907920316e-16,
-0.4714045207910316,
1.4802973661668753e-16,
0.3450920601366943]
for v in vals:
to_frational(v)
0 0 725023865223831/562949953421312 32197527542969/25000000000000 2627099782632789/10141204801825835211973625643008 259052039079203/1000000000000000000000000000000 -8492068896701029/18014398509481984 -sqrt(2)/3 6004799503160661/40564819207303340847894502572032 9251858538543/62500000000000000000000000000 6216625893760533/18014398509481984 172546030068347/500000000000000
