We will be considering continued fractions of the form
a0+a1+⋱+an−1+an1111
where the ak's are real numbers called the partial quotients. Continued fractions can be greatly generalized, where both the “numerators” (here all equal to one) and the partial quotients can be more general mathematical objects. Most common, however, are regular continued fractions where a0 is an integer and a1,…,an are positive integers. For easier notation we introduce
From (3), (4), and (5) we see that any continued fraction can be written without a zero element (the first partial quotient a0 may be zero, though) and without the last element being equal to one. For instance,
//0,4,3,0,2,1//=4+//3,0,2,1//=4+//5,1//=4+//6//.
Continuants
We now turn to continuant polynomials or simply continuants. They are defined as
K0()=1,
K1(x1)=x1,
Kn(x1,…,xn)=Kn−1(x1,…,xn−1)xn+Kn−2(x1,…,xn−2) for n≥2.
The subscripts are included to make clear how many parameters there are. Note how
(6)
Fn+1=Kn(1,…,1),
where F0,F1,… are the well-known Fibonacci numbers (F0=F1=0 and Fk=Fk−1+Fk−2 for k≥2). This is easily seen by setting xk=1 for all k in the definition.
We also have
(7)
Kn(x1,…,xn)≥K(y1,…,yn),when xk≥yk,
which can be shown straightforwardly by induction. We will use this fact later on.
Continuants are connected to continued fractions in several ways, an essential one being
This shows that when u=Kn+1(a0,a1,…,an) and v=Kn(a1,a2,…,an) then not only is u/v=a0+//a1,a2,…,an//, but u and v are also relatively prime.
Evaluating Continued Fractions
Let us consider how to evaluate a continued fraction in C++, given access to the partial quotients a0,a1,…,an through a forward iterator. One way is to use Equation (1) which leads to
template<typenameNUM,typenameIn>
NUM evaluate_continued_fraction_rec(In first, In last){if(first == last)return(NUM)0;return*first +evaluate_continued_fraction_rec2<NUM>(first+1, last);}
where //a1,a2,…,an// is evaluated recursively by
template<typenameNUM,typenameIn>
NUM evaluate_continued_fraction_rec2(In first, In last){if(first == last)return(NUM)0;return1/(*first +evaluate_continued_fraction_rec2<NUM>(first+1, last));}
A drawback to this approach is the recursive calls. Another way to evaluate is to use a special case of Equation (2),
template<typenameNUM,typenameBi>
NUM evaluate_continued_fraction_rev(Bi first, Bi last){if(last == first)return(NUM)0;
NUM r =0;while(--last != first)
r =1/(*last + r);return*last + r;}
Using continuants, we can actually evaluate a continued fraction using a forward iterator and without any recursive calls. The key is to use the relation (8) which leads to the following algorithm.
template<typenameNUM,typenameIn>voidevaluate_continued_fraction(In first, In last, NUM& num, NUM& den){if(first == last){ num =0; den =1;return;}
NUM x, u =*first, v =1, s =1, t =0;while(true){if(++first == last){ num = u; den = v;return;}
x =*first;
s += x*u;
t += x*v;if(++first == last){ num = s; den = t;return;}
x =*first;
u += x*s;
v += x*t;}}
Note how the result is seperated into numerator and denominator. Recall from the previous section that the corresponding fraction is guaranteed to be at its lowest terms.
Constructing a Continued Fraction
Let x be a real number. Consider now the following sequences:
If xk=0 then ak+1,… are undefined and x=a0+//a1,a2,…,an// with n=k. If all xk's are non-zero then x=a0+//a1,a2,…//, but we will delay the argument of why this infinite continued fraction makes sense until the final section.
It should be clear from the previous section that the value of the a regular continued fraction is a rational number. So let us try to reverse the process when x is a rational number. Given x=u/v with integer u and positive integer v, how can a0,a1,… be computed? Setting uk/vk=xk in the construction process from above, we get
a0=⌊vu⌋,ak+1=⌊ukvk⌋,v0u0=vu−a0=vu−⌊u/v⌋v=vu mod v,vk+1uk+1=ukvk−ak+1=ukvk−⌊vk/uk⌋uk=ukvk mod uk,
for k=0,1,…. If this is turned into a C++ algorithm, we get the following. (The main loop has been unrolled to avoid the u↔v swapping and a little tweaking was also necessary when the algorithm starts because C++ integer division u/v is not always equal to ⌊u/v⌋ when the result is negative.)
template<typenameNUM,typenameOut>voidfraction_to_continued_fraction(NUM u, NUM v, Out out){if(v <0){ u =-u; v =-v;}
NUM r = u % v;if(r <0){ u -= v; r += v;}*out++= u/v;
u = r;while(true){if(!u)return;*out++= v/u;
v %= u;if(!v)return;*out++= u/v;
u %= v;}}
Notice the resemblence to computing the greatest common divisor using Euclid's algorithm. In fact, the values of u and v are equivalent to those during the gcd_euclid function of that article. Furthermore, Euclid's algorithm always terminates, so the construction process always terminates when the input number is rational. In fact, a continued fraction is finite if and only if it represents a rational number.
Infinite Continued Fractions
Let us consider the construction of a continued fraction for any real number x. Recall that at any stage of the construction, we have
x=a0+//a1,a2,…,ak+xk//.
How close is x to a0+//a1,a2,…,ak// for some k? We get
using (1), (8), (11), and (12). This relation shows several important things (which also hold for finite continued fractions x=a0+//a1,a2,…,an// when k<n):
a0+//a1,a2,…,ak// is less than x for even k and greater than x for odd k.
Using (8) and (9) we see that the function y↦a0+//a1,a2,…,ak+y// is continuous and strictly increasing (k even) or strictly decreasing (k odd) when y goes from 0 to 1, and since 0<xk<1 we have that x always lies betweena0+//a1,a2,…,ak// and a0+//a1,a2,…,ak+1//.
The denominator of the error term grows, at least, exponentially (using (6), (7) and with ϕ=(1+5)/2∼1.618),
where each fraction is a better and better approximation to e (the absolute error for 49171/18089 is around −3⋅10−10).
As mentioned earlier, the continued fraction of some x is finite if and only if x is rational. The continued fraction representation for x is infinite and eventually periodic,
a0+//a1,…,am,b1,…,bn,b1,…,bn,…//,m≥0,n≥1,
if and only if x is a quadratic irrationality (proved in TAOCP, vol. 2, Exercise 4.5.3-12). A quadratic irrationality is a number of the form (d−u)/v where d, u, and v are integers, d>0, v=0, and d is not a perfect square.
Some special cases of this theorem are:
n2+1=n+//2n,2n,…//,
n2+2=n+//n,2n,n,2n,…//,
for positive integers n. To prove the first of these identities let x=n+//2n,2n,…//. Then x−n=y where y=1/(2n+y), implying x−n=1/(x+n) and finally x2−n2=1. The second identity can be proved similarly.
Concluding Remarks
This article on continued fractions was supposed to be fairly short and just contain the most basic properties, but the subject turned out to be vast and very interesting. More articles related to continued fractions will likely follow.