Continued Fraction Arithmetic

The standard forms of numerical representation on computers are of course, integers and floating point numbers, depending on need. In cases where arbitrary precision is desired (as dgw25 and ecowatcher pointed out), one can turn to iterative methods and string representation to try to reach the desired level of precision. But let’s be honest here–this is basically an inelegant hack, and its drawbacks show up in a number of ways:

  •  We need to choose your desired level of accuracy from the beginning. For example, if we are adding two large numbers, then we must start the calculation from the right hand side, due to the leftward propagation of carry. If we later change our minds, then the entire calculation must often be repeated.
  • Why decimal? The choice of base is somewhat arbitrary, but can have significant effects on the accuracy of the calculation. The common example of 1/3 = 3.33333…. comes to mind. Although there is no exactly base-10 representation, if we switch to base-3 then we easily get full accuracy. But as far as I know, there is no software that will do string arithmetic in arbitrary bases.
  • More pertinently, rational numbers are in some sense the ‘low-hanging fruit’ of the number line, since they have exact, finite, unique expressions. Decimal expansion throws that straight out the window.
  • Decimal expansions are not unique. In decimal, the infinite expansion 9.9999… = 10, for example. Then we are left with special cases: let’s say we have two digits of accuracy. Then we can definitely distinguish between 9.96 and 9.95, but 9.99 and 10.00 may or may not be the same number.

Luckily, we have mathematicians who think of newer and zanier ways of writing down numbers in their spare time (if you don’t believe me, Google p-adic numbers and surreal numbers). In any case, what’s a course in numerical analysis without exploring different ways to represent numbers, right? One particularly elegant way of writing numbers are as continued fractions. I’m sure most of you have seen them before, but for those who haven’t, le voilà:  cf1 Don’t panic! Despite the cumbersome-looking construction, what this expression really says is “n is about a_0. But just a little bit more: 1/a_1 more. But did we say a_1? We meant a_1 + 1/a_2. But slightly more than a_2…” In this way, successive terms in the continued fraction expansion approximate n better and better. One can store continued fractions simply as lists of integers: [a_0, a_1, a_2, … ]. There are a number of beautiful theorems regarding continued fractions that imply ease of handling:

  • All rational numbers have finite continued fraction expansions (the converse is also true)
  • Many irrational numbers (roots of polynomials, some transcendentals) have periodic or regular expansions. For example, e = [2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, …]
  • For almost all (this is math-speak for “with probability 1″) real numbers, the geometric mean of the terms in its expansion are approximately 2.68. This is known as Khinchin’s constant, and shows that for basically all numbers, we are guaranteed to encounter only small terms.
  • Truncating an expansion gets us very close to the true value. In fact, a truncated continued fraction represents a best rational approximation, in the sense that any approximation with a smaller denominator is necessarily worse. 
  • Even better, we automatically know what the error bound is due to the form of the fraction.

These properties may be all well and good, but how do we actually do math with continued fractions? As it turns out, we can regard a number n as an object that, when invoked, provides the next term in its fractional expansion. Then whenever we perform a calculation, say x = sqrt(n), we simply create a new object x that has the same form. When x is queried, it either spits out the next term in its expansion, or if it doesn’t have enough information, it first queries n before replying. The actual details of how to do addition, subtraction, multiplication, and root-finding with continued fractions are a little involved, and the links below provide additional details. However, a few advantages over decimal (or n-ary) expansion come to mind:

  • Converting to and from decimal expansions is easy 
  • Evaluation is done from greatest-significance to least-significance, in contrast to decimal arithmetic which goes the other way around. We can provisionally use the first terms while waiting for more terms to come out.
  • Once a ‘number object’ spits out a term, we can take it for certain that it’s correct.
  • Actual calculations are done on small integers, meaning they are exact calculations that don’t involve the floating-point unit at all!
  • If we decide at some point that we need more accuracy, we can simply ask the number object for an additional term.

That’s it for this short intro. Code samples and details on how to do math with continued fractions:http://www.inwap.com/pdp10/hbaker/hakmem/cf.htmlhttp://en.wikipedia.org/wiki/Continued_fractionhttp://en.wikipedia.org/wiki/Continued_fraction

Posted in Topics: Uncategorized

Jump down to leave a comment.

Leave a Comment

You must be logged in to post a comment.



* You can follow any responses to this entry through the RSS 2.0 feed.