When the integers run out
With the integers you can always add, subtract and multiply. But you cannot always divide.
- Three friends in Lagos share 2 litres of zobo, a hibiscus drink. Each gets litres — and no integer is .
- An underwater robot surveying a reef off Mombasa sinks from the surface to metres in 6 equal stages. Each stage changes its depth by metres — a negative number that is not a whole number.
To divide freely we need fractions, positive and negative. They raise some surprising questions:
- Is there a smallest positive fraction — a number “just after” ?
- Why does repeat the same six digits for ever?
- Is (nines for ever) a little less than , or equal to it?
- If we mark every fraction on the number line, is the line full?
By the end of this lesson you will be able to answer all four — with proofs.
Fractions on both sides of zero
You already know fractions such as from fractions and decimals: cut each unit into equal parts and take of them. Negative fractions are their mirror images on the other side of zero, exactly as mirrors .
Look between and : there is . Between and : there is . Cutting into smaller and smaller parts, we keep finding new points.
Definitions
Definition— rational number
A rational number is a number that can be written as , where and are integers and . The set of all rational numbers is written (for quotient).
One rational number has many names: . The rule for when two names mean the same number is
(Multiply both sides of by to get ; divide by to go back.) For example, because .
- Signs. . We usually make the denominator positive.
- Simplest form. A fraction is in simplest form (lowest terms) when and and have no common factor bigger than . Every rational number has exactly one simplest form; the proof uses facts about primes from divisibility.
- Integers are rational. Every integer equals , so .
The four operations are defined by the familiar fraction rules, now allowing negative numerators:
Definition— reciprocal
The reciprocal of a number is a number with . The reciprocal of (with ) is . Dividing by a non-zero number means multiplying by its reciprocal:
Definition— terminating and repeating decimals
A decimal terminates if it stops: . A decimal eventually repeats if, from some place on, one block of digits repeats for ever. We mark the block with a bar: and
A terminating decimal can be seen as repeating the block for ever: .
Worked examples
Example— Adding and subtracting with negatives
- .
- .
As with integers, subtracting means adding the opposite: .
Example— Multiplying and dividing with negatives
- . The sign rules are the ones proved in the integers lesson.
- .
- The robot: metres per stage.
Example— Dividing by a half doubles
. It makes sense: “how many halves fit into ?” Six. Dividing by a number between and makes a positive number bigger.
Example— Fractions to decimals
-
: since , . It terminates.
-
by long division. Keep track of the remainders:
- : digit , remainder ;
- : digit , remainder ;
- : digit , remainder — the same remainder again!
From now on every step is the same, so .
Example— Non-examples
- The decimal (one more each time) never settles into a repeating block, so — by a theorem below — it is not a rational number.
- and are not rational numbers. For we prove it in this lesson; for the proof (Lambert, 1761) is harder.
The main results, with proofs
Theorem— Theorem 1 (closure)
If and are rational, then so are , and , and so is if .
Proof
Write and with integers and . Then
The numerators and denominators are integers, and because a product of non-zero integers is non-zero. If , then (otherwise ), so with .
∎
Theorem— Theorem 2 (reciprocals)
Every non-zero rational number has a reciprocal that is also rational. The number has no reciprocal.
Proof
If then , so is a rational number, and . For : every has .
∎
This fills the empty box from the integers lesson, where only and had reciprocals. A number system in which you can add, subtract, multiply, and divide by anything non-zero, with the usual rules, is called a field — is the first field most people meet.
Theorem— Theorem 3 (density)
If and are rational numbers with , then their average is rational and .
Proof
is rational by closure. From , adding to both sides gives , so . Adding instead gives , so .
∎
So there is no smallest positive rational number (question 1): if were the smallest, then would be a smaller positive rational. Repeating the averaging shows there are infinitely many rationals between any two.
Theorem— Theorem 4 (decimals of fractions repeat)
Let and be integers. The decimal expansion of either terminates or eventually repeats. If it does not terminate, the repeating block has at most digits.
Proof
In long division by , each step takes the current remainder , with , and divides by : . The next digit and the next remainder depend only on .
There are only possible remainders: . So among the first remainders, two must be equal — this is the pigeonhole principle: pigeons in holes means some hole holds two. Once a remainder comes back, the computation from that point on is an exact copy of what happened after its first appearance, so the digits repeat (question 2).
If the remainder ever appears, all later digits are and the decimal terminates. Otherwise only the remainders occur, so a repeat happens within steps and the block has at most digits.
∎
For the block has the largest length allowed, : all six non-zero remainders appear before one repeats.
Theorem— Theorem 5 (which fractions terminate)
A fraction in simplest form has a terminating decimal exactly when has no prime factors other than and .
Proof
If , let be the larger of and . Then , so , which terminates after places.
Conversely, if for an integer , then , so divides . Since and have no common factor, must divide (this step is Euclid's lemma about primes). The only prime factors of are and , so the same is true of .
∎
Theorem— Theorem 6 (repeating decimals are fractions)
Every terminating or eventually repeating decimal is a rational number.
Proof
A terminating decimal with places is an integer divided by . Now take a purely repeating decimal, say . Shifting the decimal point two places gives , so and . In general, if and is the whole number , then , so
If some digits come before the block, as in , first shift them past the point: , so . By closure, the result is always rational.
∎
Note
“Shift the point and subtract the infinite tail” treats an infinite decimal as a number. That is justified once we define an infinite decimal to mean the number its finite truncations approach — the subject of sequences and series. Here we use it as known.
Theorem— Theorem 7
.
Proof
Theorem 6 with and gives . Here is a second argument that avoids shifting an infinite decimal. The number with nines, , equals . If were less than , the gap would be a positive number. But is at least for every , so for every . That is impossible for a positive : choose so large that . So the gap is (question 3).
∎
and are two names for the same number, just as and are. In fact, every terminating decimal other than has a second name ending in nines:
A gap in the rational line
Now question 4. Draw a square with sides of length . By the Pythagorean theorem its diagonal satisfies . Swing the diagonal down onto the number line with a compass: it marks a real point, . Is that point one of the fractions?
Theorem— Theorem 8 (√2 is irrational)
There is no rational number whose square is .
Proof
Suppose, for contradiction, that with in simplest form. Then , so is even. If were odd, would be odd (odd times odd is odd); so is even, say . Then , so , which is even, so is even too. But then is a common factor of and , contradicting simplest form. So no such fraction exists.
∎
So even after every fraction is marked, the number line has a hole at — and, it turns out, infinitely many other holes (, , …). The rationals are dense (no interval is free of them) but not complete (they have gaps). Filling the gaps gives the real numbers.
Rational numbers in Lean
Core Lean already contains the rational numbers as the type Rat. Each value is stored in simplest form: an integer numerator, a positive denominator, and a proof that they share no factor. We start with the lesson's definition and check that Lean's Rat matches it.
/-- A number `x` is a *quotient of integers* if `x = m / n` for some integers `m` and `n`
with `n ≠ 0`. This is the lesson's definition of a rational number. -/
def IsQuotient (x : Rat) : Prop := ∃ m n : Int, n ≠ 0 ∧ x = (m : Rat) / (n : Rat)/-- Every value of Lean's type `Rat` is a quotient of integers: `q = q.num / q.den`.
So Lean's `Rat` really is the set of fractions of the lesson. This applies the core lemmas
`Rat.num_divInt_den` and `Rat.divInt_eq_div`. -/
theorem every_rat_is_quotient (q : Rat) : IsQuotient q := by
refine ⟨q.num, (q.den : Int), ?_, ?_⟩
· exact Int.ofNat_ne_zero.mpr q.den_nz
· rw [← Rat.divInt_eq_div]
exact (Rat.num_divInt_den q).symmClosure. The addition formula, and closure under addition and division, mirror the proof of Theorem 1. A few routine algebra steps are closed by grind, Lean's built-in automatic prover, which knows the rules of fraction arithmetic.
/-- The rule for adding fractions: `a/b + c/d = (a·d + b·c)/(b·d)` when `b, d ≠ 0`.
Rewrite both fractions over the common denominator `b·d`, then add the numerators. -/
theorem add_formula (a b c d : Int) (hb : b ≠ 0) (hd : d ≠ 0) :
(a : Rat) / b + (c : Rat) / d = ((a * d + b * c : Int) : Rat) / ((b * d : Int) : Rat) := by
have hb' := int_cast_ne_zero hb
have hd' := int_cast_ne_zero hd
push_cast
calc (a : Rat) / b + (c : Rat) / d
= (a * d) / (b * d) + (b * c) / (b * d) := by grind
_ = (a * d + b * c) / (b * d) := by grind/-- **Closure under addition.** The sum of two quotients of integers is a quotient of
integers: the witness is the numerator `a·d + b·c` over the denominator `b·d` from
`add_formula`, and `b·d ≠ 0` because neither factor is zero. -/
theorem closed_add {x y : Rat} (hx : IsQuotient x) (hy : IsQuotient y) :
IsQuotient (x + y) := by
obtain ⟨a, b, hb, rfl⟩ := hx
obtain ⟨c, d, hd, rfl⟩ := hy
exact ⟨a * d + b * c, b * d, Int.mul_ne_zero hb hd, add_formula a b c d hb hd⟩/-- **Closure under division by a non-zero number.** If `y = c/d ≠ 0` then `c ≠ 0`, and
`(a/b) ÷ (c/d) = (a/b)·(d/c) = (a·d)/(b·c)`: divide by multiplying by the reciprocal. -/
theorem closed_div {x y : Rat} (hx : IsQuotient x) (hy : IsQuotient y) (hy0 : y ≠ 0) :
IsQuotient (x / y) := by
obtain ⟨a, b, hb, rfl⟩ := hx
obtain ⟨c, d, hd, rfl⟩ := hy
have hb' := int_cast_ne_zero hb
have hd' := int_cast_ne_zero hd
have hc : c ≠ 0 := by
intro hc
apply hy0
subst hc
simp [Rat.div_def]
have hc' := int_cast_ne_zero hc
refine ⟨a * d, b * c, Int.mul_ne_zero hb hc, ?_⟩
push_cast
grindReciprocals. First our own proof of Theorem 2, then the one-line version that applies core Lean's library theorem Rat.mul_inv_cancel, then the fact that has no reciprocal, and division by a half.
/-- The reciprocal of `a/b` is `b/a`: if `a, b ≠ 0` then `(a/b)·(b/a) = (a·b)/(b·a) = 1`. -/
theorem mul_reciprocal (a b : Int) (ha : a ≠ 0) (hb : b ≠ 0) :
((a : Rat) / b) * ((b : Rat) / a) = 1 := by
have ha' := int_cast_ne_zero ha
have hb' := int_cast_ne_zero hb
calc ((a : Rat) / b) * ((b : Rat) / a)
= ((a : Rat) * b) / ((b : Rat) * a) := by grind
_ = 1 := by grind/-- Every non-zero rational number has a multiplicative inverse in `Rat`, unlike in `Int`
(where only `1` and `-1` do). This applies core Lean's `Rat.mul_inv_cancel`. -/
theorem reciprocal_exists (q : Rat) (hq : q ≠ 0) : ∃ r : Rat, q * r = 1 :=
⟨q⁻¹, Rat.mul_inv_cancel q hq⟩/-- Zero has no reciprocal: `0 · r = 0 ≠ 1` for every `r`. -/
theorem zero_no_reciprocal : ¬ ∃ r : Rat, 0 * r = 1 := by
intro ⟨r, h⟩
rw [Rat.zero_mul] at h
exact absurd h (by decide)/-- Dividing by `1/2` doubles: `x ÷ (1/2) = 2x`. Division is multiplication by the reciprocal,
and the reciprocal of `1/2` is `2`. -/
theorem div_half (x : Rat) : x / (1 / 2) = 2 * x := by
grindDensity (Theorem 3), following the human proof line by line:
/-- If `a < b` then the average `(a + b)/2` lies strictly between them:
`a = (a + a)/2 < (a + b)/2 < (b + b)/2 = b`. -/
theorem average_between {a b : Rat} (h : a < b) : a < (a + b) / 2 ∧ (a + b) / 2 < b := by
have two_pos : (0 : Rat) < 2 := by decide
constructor
· -- `a < (a + b)/2` is the same as `a · 2 < a + b`, i.e. `a + a < a + b`.
rw [Rat.lt_div_iff two_pos]
have : a + a < a + b := Rat.add_lt_add_left.mpr h
grind
· -- `(a + b)/2 < b` is the same as `a + b < b · 2`, i.e. `a + b < b + b`.
rw [Rat.div_lt_iff two_pos]
have : a + b < b + b := Rat.add_lt_add_right.mpr h
grind/-- **Density of the rationals.** Between any two different rationals there is a third, so no
rational number has a "next" one. The witness is the average (`average_between`). -/
theorem exists_between {a b : Rat} (h : a < b) : ∃ c : Rat, a < c ∧ c < b :=
⟨(a + b) / 2, average_between h⟩Decimals by long division (Theorem 4). We define the remainders and digits of long division, prove that the -th remainder is modulo , prove the pigeonhole principle, and conclude that the digits are eventually periodic with period at most .
/-- The remainders in the long division of `a` by `b`. Start with `a % b`; at each step
"bring down a zero": multiply the remainder by `10` and take the remainder on division by `b`. -/
def rem (a b : Nat) : Nat → Nat
| 0 => a % b
| k + 1 => (10 * rem a b k) % b/-- The digit produced at step `k + 1` of the long division of `a` by `b`: how many times `b`
goes into ten times the current remainder. `digit a b 0` is the first digit after the point. -/
def digit (a b k : Nat) : Nat := (10 * rem a b k) / b/-- The `k`-th remainder is the remainder of `a · 10^k` on division by `b`: long division
really is computing `a · 10^k` modulo `b`. Proof by induction, using `(x % b) · 10 ≡ x · 10`. -/
theorem rem_eq (a b k : Nat) : rem a b k = a * 10 ^ k % b := by
induction k with
| zero => simp [rem]
| succ k ih =>
rw [rem, ih, Nat.mul_mod, Nat.mod_mod, ← Nat.mul_mod, Nat.pow_succ]
congr 1
rw [Nat.mul_comm 10, Nat.mul_assoc]/-- Once a remainder repeats, everything after it repeats: each remainder is computed from the
one before, so if `rem i = rem j` then `rem (i + n) = rem (j + n)` for every `n`. -/
theorem rem_periodic (a b : Nat) {i j : Nat} (h : rem a b i = rem a b j) :
∀ n, rem a b (i + n) = rem a b (j + n) := by
intro n
induction n with
| zero => exact h
| succ n ih =>
rw [← Nat.add_assoc, ← Nat.add_assoc, rem, rem, ih]/-- **The pigeonhole principle** for the values `f 0, f 1, …, f b`: if all `b + 1` of them are
less than `b`, two of them are equal. Proof by induction on `b`: either `f (b + 1)` already
appeared, or we relabel the value `b` as `f (b + 1)` and use the induction hypothesis. -/
theorem pigeonhole : ∀ (b : Nat) (f : Nat → Nat), (∀ k, k ≤ b → f k < b) →
∃ i j, i < j ∧ j ≤ b ∧ f i = f j := by
intro b
induction b with
| zero =>
intro f hf
exact absurd (hf 0 (Nat.le_refl 0)) (Nat.not_lt_zero _)
| succ b ih =>
intro f hf
by_cases hrep : ∃ k, k ≤ b ∧ f k = f (b + 1)
· obtain ⟨k, hk, hfk⟩ := hrep
exact ⟨k, b + 1, by omega, Nat.le_refl _, hfk⟩
· -- `f (b + 1)` is new. Replace the value `b` (if it occurs) by `f (b + 1)`.
have hnew : ∀ k, k ≤ b → f k ≠ f (b + 1) := fun k hk h => hrep ⟨k, hk, h⟩
let g : Nat → Nat := fun k => if f k = b then f (b + 1) else f k
have hg : ∀ k, k ≤ b → g k < b := by
intro k hk
have h1 := hf k (by omega)
have h2 := hf (b + 1) (Nat.le_refl _)
have h3 := hnew k hk
simp only [g]
split <;> omega
obtain ⟨i, j, hij, hjb, hgij⟩ := ih g hg
refine ⟨i, j, hij, by omega, ?_⟩
have hi := hnew i (by omega)
have hj := hnew j hjb
simp only [g] at hgij
split at hgij <;> split at hgij <;> omega/-- In the long division of `a` by `b > 0`, some remainder repeats within the first `b + 1`
steps: the remainders take at most `b` values (`rem_lt`), so `pigeonhole` applies. -/
theorem remainder_repeats (a b : Nat) (hb : 0 < b) :
∃ i j, i < j ∧ j ≤ b ∧ rem a b i = rem a b j :=
pigeonhole b (rem a b) (fun k _ => rem_lt a b k hb)/-- **The decimal expansion of `a/b` is eventually periodic.** There is a starting place `i`
and a period `p` with `1 ≤ p ≤ b` such that the digits repeat with period `p` from place `i`
on. (A terminating decimal is the case where the repeating block is `0`.) -/
theorem decimal_eventually_periodic (a b : Nat) (hb : 0 < b) :
∃ i p, 0 < p ∧ p ≤ b ∧ ∀ n, digit a b (i + p + n) = digit a b (i + n) := by
obtain ⟨i, j, hij, hjb, h⟩ := remainder_repeats a b hb
refine ⟨i, j - i, by omega, by omega, ?_⟩
intro n
have hji : i + (j - i) = j := by omega
unfold digit
rw [hji, rem_periodic a b h.symm n]/-- The first twelve digits of `1/7 = 0.142857142857…`, computed by the long-division
definitions above and checked by evaluation. -/
theorem one_seventh_digits :
(List.range 12).map (digit 1 7) = [1, 4, 2, 8, 5, 7, 1, 4, 2, 8, 5, 7] := by
decideBack to fractions, and (Theorems 6 and 7). Again we prove the finite facts: the shift-and-subtract equation forces , the number with nines falls short of by exactly , and that gap can be made smaller than any positive rational.
/-- If shifting the decimal point `k ≥ 1` places gives the repeating block `D` plus the
number itself, `10^k · x = D + x`, then `x = D / (10^k - 1)`. For `x = 0.272727…`,
`100x = 27 + x`, so `x = 27/99`. -/
theorem repeating_to_fraction (x D : Rat) (k : Nat) (hk : 1 ≤ k) (h : 10 ^ k * x = D + x) :
x = D / (10 ^ k - 1) := by
have hpow : (10 : Rat) ≤ 10 ^ k := by
have h10 : (10 : Nat) ≤ 10 ^ k := by
calc 10 = 10 ^ 1 := rfl
_ ≤ 10 ^ k := Nat.pow_le_pow_right (by decide) hk
have := Rat.natCast_le_natCast.mpr h10
simpa using this
have hne : (10 : Rat) ^ k - 1 ≠ 0 := by
intro h0
have : (10 : Rat) ^ k = 1 := by grind
rw [this] at hpow
exact absurd hpow (by decide)
grind/-- The number `0.99…9` with `n` nines is `1 - 1/10^n`: its gap below `1` is exactly
`1/10^n`. As `n` grows, this gap becomes smaller than any positive number. -/
theorem nines_gap (n : Nat) : 1 - ((10 : Rat) ^ n - 1) / 10 ^ n = 1 / 10 ^ n := by
have hpos : (0 : Rat) < 10 ^ n := Rat.pow_pos (by decide)
have hne : (10 : Rat) ^ n ≠ 0 := Rat.ne_of_gt hpos
grind/-- For every positive rational `ε` there is an `n` with `1/10^n < ε`. Together with `nines_gap`
this is why `0.999… = 1`: the distance from `0.999…` up to `1` is below every positive
number, so it is `0`. Proof: take `n = ⌈1/ε⌉`; then `1/ε ≤ n < 10^n`. -/
theorem gap_lt_every_positive (ε : Rat) (hε : 0 < ε) : ∃ n : Nat, 1 / (10 : Rat) ^ n < ε := by
refine ⟨(1 / ε).ceil.toNat, ?_⟩
have hinvpos : 0 < 1 / ε := by
rw [Rat.lt_div_iff hε]
simpa using (show (0 : Rat) < 1 by decide)
have hceil : 1 / ε ≤ ((1 / ε).ceil : Rat) := Rat.le_ceil
have hceil_nonneg : 0 ≤ (1 / ε).ceil := by
have : (0 : Rat) ≤ ((1 / ε).ceil : Rat) := Rat.le_trans (Rat.le_of_lt hinvpos) hceil
exact Rat.intCast_nonneg.mp this
have hcast : (((1 / ε).ceil.toNat : Nat) : Rat) = ((1 / ε).ceil : Rat) := by
rw [← Rat.intCast_natCast, Int.toNat_of_nonneg hceil_nonneg]
have hpow : ((1 / ε).ceil.toNat : Rat) < (10 : Rat) ^ (1 / ε).ceil.toNat := by
have := Rat.natCast_lt_natCast.mpr
(Nat.lt_pow_self (n := (1 / ε).ceil.toNat) (a := 10) (by decide))
simpa using this
have hlt : 1 / ε < (10 : Rat) ^ (1 / ε).ceil.toNat := by
rw [hcast] at hpow
grind
have h10pos : (0 : Rat) < 10 ^ (1 / ε).ceil.toNat := Rat.pow_pos (by decide)
rw [Rat.div_lt_iff h10pos]
rw [Rat.div_lt_iff hε] at hlt
grindNo rational square root of (Theorem 8). Lean's proof avoids “simplest form” and uses Fermat's infinite descent instead: a solution of with would give a smaller one, , and whole numbers cannot get smaller for ever. It is the same idea — dividing out a again and again — organised differently.
/-- If `a · a` is even then `a` is even: an odd number times an odd number is odd. -/
theorem even_of_sq_even (a : Nat) (h : a * a % 2 = 0) : a % 2 = 0 := by
rcases Nat.mod_two_eq_zero_or_one a with h0 | h1
· exact h0
· rw [Nat.mul_mod, h1] at h
exact absurd h (by decide)/-- **No whole-number solution to `a² = 2b²` except `b = 0`** (Fermat's infinite descent).
If `a² = 2b²` with `b > 0`, then `a` is even, `a = 2c`, so `b² = 2c²`: a smaller solution
`(b, c)`, since `b < a`. Smaller and smaller solutions cannot go on for ever. -/
theorem sq_two_descent : ∀ a b : Nat, a * a = 2 * (b * b) → b = 0 := by
intro a
induction a using Nat.strongRecOn with
| _ a ih =>
intro b hab
-- `a` is even.
have heven : a % 2 = 0 := by
apply even_of_sq_even
rw [hab, Nat.mul_mod_right]
obtain ⟨c, rfl⟩ : ∃ c, a = 2 * c := ⟨a / 2, by omega⟩
-- Cancel a factor 2: `b * b = 2 * (c * c)`.
have hbc : b * b = 2 * (c * c) := by
have h4 : 2 * (2 * (c * c)) = 2 * (b * b) := by
rw [← hab]; grind
omega
by_cases hb : b = 0
· exact hb
· -- `b < 2c`, because `b ≥ 2c` would give `b² ≥ 4c² > 2c²`.
have hlt : b < 2 * c := by
apply Nat.lt_of_not_le
intro hle
have hsq : (2 * c) * (2 * c) ≤ b * b := Nat.mul_le_mul hle hle
have hbpos : 0 < b * b := Nat.mul_pos (by omega) (by omega)
omega
have hc : c = 0 := ih b hlt c hbc
subst hc
simp at hbc
exact (Nat.mul_eq_zero.mp hbc).elim id id/-- **There is no rational number whose square is 2.** Writing `q = num/den`, `q² = 2` gives
`num² = 2 · den²`; taking absolute values gives whole numbers `a, b` with `a² = 2b²` and
`b = den ≠ 0`, which `sq_two_descent` rules out. So the rational number line has a gap
where `√2` should be. -/
theorem no_rat_sq_two : ¬ ∃ q : Rat, q * q = 2 := by
intro ⟨q, hq⟩
have hsq : q ^ 2 = 2 := by rw [← hq]; grind
-- Compare numerators and denominators: `num(q²) · den(2) = num(2) · den(q²)`.
have hcross := Rat.eq_iff_mul_eq_mul.mp hsq
rw [Rat.num_pow, Rat.den_pow] at hcross
have hint : q.num * q.num = 2 * ((q.den : Int) * (q.den : Int)) := by
have h2n : (2 : Rat).num = 2 := rfl
have h2d : (2 : Rat).den = 1 := rfl
rw [h2n, h2d] at hcross
simp only [Int.pow_succ, Int.pow_zero, Int.one_mul, Int.natCast_pow] at hcross
grind
have hnat : q.num.natAbs * q.num.natAbs = 2 * (q.den * q.den) := by
have := congrArg Int.natAbs hint
rw [Int.natAbs_mul, Int.natAbs_mul, Int.natAbs_mul] at this
simpa using this
exact q.den_nz (sq_two_descent _ _ hnat)Not formalised here: Theorem 5 (the -and- rule), and the meaning of infinite decimals as limits.
Long division by machine
"""Long division by hand, done by machine: why decimals of fractions repeat.
Dividing a by b, each step leaves a remainder 0, 1, ..., b - 1. As soon as a
remainder comes back, the digits after it repeat for ever. This experiment
runs long division with exact integers, records the remainders, and reports
where the repeating block starts and how long it is. It then checks, for
every fraction a/b with 0 <= a < b <= 200, two facts proved in the lesson:
the period is at most b - 1, and the expansion terminates exactly when b (in
lowest terms) has no prime factors other than 2 and 5. Finally it turns every
expansion back into a fraction. All arithmetic is exact (no floating point).
"""
from fractions import Fraction
from math import gcd
def long_division(a, b):
"""Digits of a/b after the point, for 0 <= a and b > 0.
Returns (whole, digits, start, period): a/b = whole + 0.d1 d2 d3 ...,
the digits from index ``start`` on repeat with length ``period``.
A terminating decimal has repeating block "0" (period 1, digit 0).
"""
if b <= 0 or a < 0:
raise ValueError("need a >= 0 and b > 0")
whole, r = divmod(a, b)
seen = {}
digits = []
while r not in seen:
seen[r] = len(digits)
digit, r = divmod(10 * r, b)
digits.append(digit)
start = seen[r]
return whole, digits, start, len(digits) - start
def decimal_string(a, b):
"""The expansion of a/b with the repeating block in brackets: 0.1(6)."""
whole, digits, start, period = long_division(a, b)
pre, block = digits[:start], digits[start:]
if block == [0]:
text = "".join(map(str, pre))
return f"{whole}.{text}" if text else f"{whole}"
pre_text = "".join(map(str, pre))
return f"{whole}.{pre_text}({''.join(map(str, block))})"
def only_twos_and_fives(n):
"""True if n > 0 has no prime factor other than 2 and 5."""
for p in (2, 5):
while n % p == 0:
n //= p
return n == 1
def to_fraction(whole, pre, block):
"""Exact value of whole.pre(block) where pre, block are digit strings.
x = whole + 0.pre(block); shifting by the block length k and
subtracting removes the infinite tail: (10**k - 1) * 10**m * x is an
integer, where m = len(pre).
"""
m, k = len(pre), len(block)
head = int(pre) if pre else 0
if k == 0:
return whole + Fraction(head, 10 ** m)
tail = Fraction(int(block), 10 ** k - 1)
return whole + (head + tail) / 10 ** m
def check_all(max_b):
"""Check the period bound, the 2-and-5 rule and round trips."""
cases = bad_period = bad_rule = bad_trip = 0
for b in range(1, max_b + 1):
for a in range(b):
whole, digits, start, period = long_division(a, b)
cases += 1
terminates = digits[start:] == [0]
if not terminates and period > b - 1:
bad_period += 1
if terminates != only_twos_and_fives(b // gcd(a, b)):
bad_rule += 1
pre = "".join(map(str, digits[:start]))
block = "".join(map(str, digits[start:]))
if to_fraction(whole, pre, block) != Fraction(a, b):
bad_trip += 1
return cases, bad_period, bad_rule, bad_trip
def main():
print("1/b by long division (repeating block in brackets)")
print(" b decimal period only 2s and 5s?")
for b in range(2, 18):
_, digits, start, period = long_division(1, b)
terminates = digits[start:] == [0]
per = "-" if terminates else str(period)
rule = "yes" if only_twos_and_fives(b) else "no"
print(f"{b:2d} {decimal_string(1, b):<22} {per:>6} {rule}")
print()
cases, bad_period, bad_rule, bad_trip = check_all(200)
print(f"All a/b with 0 <= a < b <= 200: {cases} fractions checked.")
print(f" period longer than b - 1: {bad_period} cases")
print(f" 2-and-5 rule wrong (either direction): {bad_rule} cases")
print(f" expansion does not convert back exactly: {bad_trip} cases")
print(f"0.(27) = {to_fraction(0, '', '27')} 0.1(6) = "
f"{to_fraction(0, '1', '6')} 0.(9) = {to_fraction(0, '', '9')}")
print()
print("Epistemic status: exact integer arithmetic, exhaustive for the")
print("20,100 fractions listed. It shows remainders repeating; it does not")
print("prove that every fraction behaves this way. The lesson's proof does:")
print("only b remainders exist, so one must repeat (pigeonhole).")
if __name__ == "__main__":
main()The table shows that , (block of digits) and others use the maximum period , while and repeat after one digit. The exhaustive check is finite evidence: impressive, but it covers only denominators up to . The pigeonhole proof covers every fraction.
"""Rationals crowd around the square root of 2, but none of them lands on it.
Three exact computations with fractions:
1. A search of every fraction p/q with 1 <= q <= 2000 for p*p == 2*q*q.
(It finds none; for each q only p near q * 1.414 needs checking.)
2. Squeezing: halve an interval [lo, hi] with lo*lo < 2 < hi*hi again and
again. The rational endpoints get as close as we like to each other, yet
neither square is ever exactly 2.
3. The fractions 1/1, 3/2, 7/5, 17/12, 41/29, ... (each p/q followed by
(p + 2q)/(p + q)) satisfy p*p - 2*q*q = +1 or -1, so their squares miss 2
by exactly 1/q**2: astonishingly close, never equal.
"""
from fractions import Fraction
from math import isqrt
def square_root_two_search(max_q):
"""All (p, q) with 1 <= q <= max_q and p*p == 2*q*q (expected: none).
For each q, the only candidate is p = isqrt(2*q*q), the largest whole
number whose square is at most 2*q*q.
"""
hits = []
for q in range(1, max_q + 1):
p = isqrt(2 * q * q)
if p * p == 2 * q * q:
hits.append((p, q))
return hits
def squeeze(steps):
"""Halve [1, 2] ``steps`` times, keeping lo*lo < 2 < hi*hi."""
lo, hi = Fraction(1), Fraction(2)
history = [(lo, hi)]
for _ in range(steps):
mid = (lo + hi) / 2
if mid * mid == 2:
raise AssertionError("found a rational square root of 2")
if mid * mid < 2:
lo = mid
else:
hi = mid
history.append((lo, hi))
return history
def pell_fractions(count):
"""The fractions p/q = 1/1, 3/2, 7/5, ... with p*p - 2*q*q = +-1."""
p, q = 1, 1
out = []
for _ in range(count):
out.append((p, q))
p, q = p + 2 * q, p + q
return out
def main():
hits = square_root_two_search(2000)
print("1. Fractions p/q with q <= 2000 and (p/q)^2 = 2:", len(hits))
print()
print("2. Squeezing between rationals (lo^2 < 2 < hi^2):")
for k, (lo, hi) in enumerate(squeeze(10)):
if k % 2 == 0:
print(f" step {k:2d}: {str(lo):>9} < sqrt 2 < {str(hi):<9}"
f" width {hi - lo}")
print()
print("3. p/q with p^2 - 2q^2 = +-1: the square misses 2 by 1/q^2")
print(" p/q p^2 - 2q^2 (p/q)^2 - 2")
for p, q in pell_fractions(8):
miss = Fraction(p * p, q * q) - 2
print(f" {p:>5}/{q:<6} {p * p - 2 * q * q:>8} {miss}")
print()
print("Epistemic status: exact, exhaustive for denominators up to 2000;")
print("the squeeze and the list show rationals getting ever closer to")
print("sqrt 2. No computation can show that no fraction ever works: that")
print("needs the proof by contradiction in the lesson.")
if __name__ == "__main__":
main()The fractions get as close to as we like: squared misses by only . But a search, however long, can never show that no fraction works. Only Theorem 8 can.
Explore: decimals creeping up on a fraction
Fractions on a number line
0.3, 0.33, 0.333 creep up on 1/3 but never reach it. Which points coincide?
- 1/3
- 0.3
- 0.33
- 0.333
- 1/2
- 3/4
- 0.75
From smallest to largest
0.3 < 0.33 < 0.333 < 1/3 < 1/2 < 3/4 = 0.75
With 3 equal parts in each whole, which points land exactly on a tick mark?
0.3 = 3/10 · 0.33 = 33/100 · 0.333 = 333/1000 · 1/3 · 1/2 = 0.5 · 3/4 = 0.75
Notice that and share one point: they are two names for one number. The truncations get ever closer to without reaching it — only the infinite decimal equals . Try typing other decimals, such as or , and find the fractions they equal.
Exercises
1. Rational numbers
Warm-upHumanCompute .
2. Rational numbers
Warm-upHumanA water seller in Kano has litres of water and fills bottles that hold litre each. How many bottles can she fill? (Compute .)
3. Rational numbers
CoreHumanCompute .
4. Rational numbers
CoreHumanWhich of these numbers have a reciprocal in ? (Choose all that apply.)
5. Rational numbers
CoreHumanWhich of these fractions have terminating decimal expansions? (Choose all that apply.)
6. Rational numbers
CoreHumanWhich fraction equals ?
7. Rational numbers
Warm-upHumanHow many rational numbers lie strictly between and ?
8. Rational numbers
StretchHumanIn the proof that is irrational we have and conclude that is even. Which reason is correct?
9. Rational numbers
CoreFormalWhich Lean statement says correctly that between any two different rational numbers there is another?
10. Rational numbers
StretchComputationalWrite period_length(a, b) for whole numbers and . Do long division: start with the remainder a % b, and at each step replace the remainder r by (10 * r) % b. Remember the step at which each remainder first appears. Return the length of the repeating block of , or 0 if the decimal terminates (that is, if the remainder 0 appears).
Common misconceptions
Misconception
“Dividing always makes a number smaller.” Dividing by a number between and makes a positive number bigger: . And dividing a negative number by makes it bigger too: , which is greater than .
Misconception
“ is just less than .” The gap would have to be smaller than for every , and the only such number that is not negative is . So (Theorem 7) — two names for one number.
Misconception
“Once every fraction is marked, the number line is full.” The fractions are dense, but (Theorem 8), , and infinitely many other numbers are missing.
Misconception
“To add fractions, add the tops and add the bottoms.” , not . (Curiously, lies between and — it is their mediant — but it is not their sum.)
Misconception
“A fraction with a big denominator has a long decimal.” terminates because , while repeats for ever. What matters is the prime factors of the denominator (Theorem 5), not its size.
Other ways of seeing
Geometry— Rational numbers are slopes through grid points
Draw the square grid of points with integer coordinates. The line from through the grid point , with , has slope — a rational number. Conversely, a line through the origin with rational slope hits the grid point . So the rational numbers are exactly the slopes of lines through the origin that meet another grid point. The line passes through no grid point except , however far you follow it: that is Theorem 8 in a picture. See the coordinate plane.
Analysis— Crowded but not complete
The truncations of are all rational, and they get closer and closer to one another — yet no rational number is the point they approach. An analyst says is dense but not complete. Building a number line with no gaps, the real numbers, is the starting point of calculus; see real numbers and irrationality and sequences and series. Another surprise: although the rationals are dense, they can be listed one after another — is countable.
Wonder Trails
Reciprocals finish the story of “undoing” multiplication; families of equal fractions are an example of sorting things into classes; and the rationals are a surprising kind of infinity. All of these are optional.
Wonder Trail · Optional · never gradedInverses and structureEvery integer can be added to another integer to get . So why can almost no integer be multiplied by another integer to get ?Follow the trail Wonder Trail · Optional · never gradedRemainder familiesSort every integer — positive, negative and zero — into families by its remainder after dividing by 3. If you add a member of one family to a member of another, does the family of the answer depend on which members you chose?Follow the trail Wonder Trail · Optional · never gradedHow many infinities?There are infinitely many counting numbers and infinitely many infinite 0–1 sequences. Are these two infinities the same size?Follow the trailSet-theoretic connection
The number systems sit inside one another: . At university you may build from : a rational number is a family of pairs of integers with , where and belong to the same family exactly when . The family of contains , , , …
For this to work, “same family” must be an equivalence relation, and the fraction rules must give answers in the same family whichever members we pick: replacing by in a sum must not change the result. Both can be proved; see constructing ℤ, ℚ and ℝ.
A glimpse of structure
is a field: addition and multiplication are commutative and associative, have identities and , are linked by the distributive law, every number has an opposite, and every non-zero number has a reciprocal. It is also the smallest field that contains the integers: any field containing (with the same addition and multiplication) contains every , and so contains a copy of . Describing an object as “the smallest one with a property” is an example of a universal property, a central idea of algebraic structures and of category theory.
History and global context
- Egypt. The Rhind Mathematical Papyrus (about 1550 BCE, copied by the scribe Ahmes from an older text) writes fractions as sums of different unit fractions, for example .
- Mesopotamia. Babylonian scribes used base- fractions. The clay tablet YBC 7289 (about 1800–1600 BCE) gives , within about of the true value.
- China. The Nine Chapters on the Mathematical Art (compiled by about the 1st century CE) gives rules for adding, subtracting, multiplying and dividing fractions, and reduces them to lowest terms by repeated subtraction — the method we now call Euclid's algorithm.
- Greece. Greek mathematicians of the 5th century BCE discovered that the side and the diagonal of a square have no common measure — in modern terms, that is irrational. Aristotle refers to a proof by odd and even numbers. Later stories attribute the discovery to the Pythagoreans; the details are uncertain.
- India and the Islamic world. Indian mathematicians wrote a fraction as one number above another; mathematicians writing in Arabic, such as al-Ḥaṣṣār in 12th-century Morocco, are usually credited with adding the horizontal bar. The earliest known decimal fractions appear in the arithmetic book of al-Uqlīdisī (Damascus, 952–953). Jamshīd al-Kāshī used them systematically in The Key to Arithmetic (Samarkand, 1427), and Simon Stevin's booklet De Thiende (1585) spread them in Europe.
- Repeating decimals. Carl Friedrich Gauss studied the lengths of the repeating blocks of in his Disquisitiones Arithmeticae (1801). Whether infinitely many primes give a block of the full length (as and do) is still unproved: it is a case of Artin's conjecture on primitive roots.
Further reading
- Ivan Niven, Numbers: Rational and Irrational (1961) — written for school students; proofs of irrationality and much more.
- Richard Courant and Herbert Robbins, What Is Mathematics? (1941), chapter II on number systems.
- John H. Conway and Richard K. Guy, The Book of Numbers (1996), for repeating decimals and the curious number .
- G. H. Hardy and E. M. Wright, An Introduction to the Theory of Numbers (1938), chapter IX on decimals — for when you are older.