[MS]: These are some notes on my playing around with [Fraction Math] and the reference to the nice notes on Continued Fractions at http://www.inwap.com/pdp10/hbaker/hakmem/cf.html [http://www.inwap.com/pdp10/hbaker/hakmem/cf.html]. I have started playing with these things and resisted (for now) looking for other sources. Some of the "errors" I found in the reference may be due to the informal presentation of results there, which might be inaccurate or misunderstood by me: ''caveat emptor''. '''DEFINITIONS:''' a rational approximation p/q to a real number x is "best" iff, for every integer r and s, (s <= q) ==> (|x - p/q| <= |x - r/s|) It is "best on its side" if ((s <= q) & (sgn(x-p/q) = sgn(x-r/s))) ==> (|x - p/q| <= |x - r/s|) i.e, if no other fraction on the same side of x with a lesser denominator comes closer. '''NOTATION:''' let us identify a (positive) real number x with its regular continued fraction representation x = {x[0] x[1] x[2] x[3] ...} Define the truncation of x after (n+1) terms a(x,n) = {x[0] x[1] x[2] x[3] ... x[n]} and let b(x,n,i) = {x[0] x[1] x[2] x[3] ... x[n-1] i} be a(x,n) with the last element replaced by 0 < i <= x[[n]]. Note that a(x,n) = b(x,n,x[n]) '''NOTE''': [[quotient_rep]] in [Fraction Math] computes the highest-order truncation requiring no integers larger than ''maxint'' in the rational representation p/q. ---- Item 101A (3) clearly says (AFAIU, not all claims reproduced here): A - a(x,n) is "best" B - b(x,n,i) is "best" if i>1 C - b(x,n,1) is never "best" if (x[n] != 1) Let me provide counterexamples to both B and C, thus showing that they are not true. The example provided in the text actually contains counterexamples to B. Let x = pi = {3 7 15 1 292 ...} . b(x,0,2) = 2/1 = {2} is not best (3/1 is better) . b(x,1,2) = 7/2 = {3 2} and b(x,1,3) = 10/3 = {3 3} are not best (3/1 is better) . b(x,2,2) = 47/15 = {3 7 2} is not best (22/7 is better) For another counterexample to B, easier to follow by hand, consider x = 0.51 = {0 1 1 24 2} The number b(x,3,4) = 5/9 = {0 1 1 4} = 0.555... is not best, as 1/2 = {0 1 1} = {0 2} is better. For a counterexample to C, consider x = 7/10 = {0 1 2 3}; now b(x,2,1) = 1/2 = {0 1 1} = {0 2} is best. ---- So, in light of these counterexamples, one proposition I can hope could be true is: D - The set of "best on its side" approximations to 0 355/113 Now, 3.1416305 = {3 7 16 2 ...},and ''quotient_rep'' produced 355/113 = {3 7 16} = a(3.1416305,2) But the fraction 377/120 = {3 7 16 1} = b(3.1416305,3,1) is closer - a new counterexample to C. Remark that the next truncation involves integers that are too large: a(3.1416305,3) = {3 7 16 2} = 732/233 ---- [Arjen Markus] Some care must be taken, as I discovered myself. I tried to deduce the continued fraction for sqrt(N^2+1)+N (forms such as sqrt(2)+1, sqrt(5)+2, ...): (sqrt(N^2+1)+N) * (sqrt(N^2+1)-N = 1 So: 1 sqrt(N^2+1)+N = ------------- sqrt(N^2+1)-N 1 = --------------------- -2N + (sqrt(N^2+1)+N) 1 = ------------------------- 1 -2N + --------------------- -2N + (sqrt(N^2+1)+N) = ... Now, the approximations are (N=1): -0.5, -0.4, ... How will this ever end up in 2.4141...? It took me the better part of an evening to realise that I had made a stupid, though understandable, mistake: the continued fraction does not get smaller! Hence my approximations are worthless. They in fact will give 1-sqrt(2). What is interesting is that these continued fractions have a natural representation in Tcl, namely lists. Try doing that with plain C! ---- '''Some code to deal with continued fractions''' a lot of this is ripped off from [KBK]'s code in [Fraction Math]. Some testing of inputs would also be needed. # # proc cont2frac # # Returns the fraction corresponding to the list # of denominators in a (truncated) regular continued # fraction. There is no check for overflow. # proc cont2frac {lst} { foreach {p q p0 q0} {1 0 0 1} break foreach a $lst { foreach {p p0} [list [expr {$a*$p+$p0}] $p] break foreach {q q0} [list [expr {$a*$q+$q0}] $q] break } list $p $q } # # proc frac2cont # # Returns list of denominators in the regular continued # expansion of frac. Cannot overflow. # proc frac2cont {frac} { foreach {p0 q0} {1 0} break foreach {p q} $frac break set clist {} while {$q} { set a [expr {$p/$q}] lappend clist $a foreach {p q} [list $q [expr {$p - $q * $a}]] break } set clist } # # proc num2cont # # Returns a list of two lists: # 1. the list of denominators in the longest truncated # regular continued fraction expansion of num with both # numerator and denominator <= maxint. # 2. the representation of the above list as a fraction # # Remark that "quotient_rep $num $maxint]" is equivalent to # "lindex [num2cont $num $maxint] 1" # proc num2cont {num { maxint 2147483647 } } { foreach {p q p0 q0} {1 0 0 1} break set clist {} while {1} { set a [expr {int($num)}] set fract [expr {$num - $a}] if {(1.0 * $a * $p + $p0 > $maxint) \ || (1.0 * $a * $q + $q0 > $maxint)} { break } lappend clist $a foreach {p p0} [list [expr {$a * $p + $p0}] $p] break foreach {q q0} [list [expr {$a * $q + $q0}] $q] break if {abs($fract * $maxint) < 1} break set num [expr {1.0 / $fract}] } list $clist [list $p $q] }