in reply to Re: Percentages to Fractions (The good, the bad and the **rediculous**)
in thread Percentages to Fractions

How to convert a float to a fraction is a topic in Knuth's Concrete Mathematics. It is based on a wierd operation which one could call "children's fractional addition" (i.e. the way a child might add fractions). This is
a c a+c --- + --- => ----- b d b+d
This is a very common children's mistake, and the result (until I saw this trick) is useful for nothing. But to find the sequence of best approximating fractions to any number, here is a bracketing algorithm based on the above operation which is fast and easy: Algorithm to approximate x (a positive real number) Start with two fractions:
a/b = 0/1 c/d = 1/0 [This is infinity, larger than any number]
create a third fraction e/f = (a+c)/(b+d) by "children adding" the two fractions Note: Do not simplify any fraction in this process. This new number will always be between the first two fractions. Discard one of the original two fractions, and replace it with the new fraction in such a way that the two fractions that are kept, still bracket the x. Keep doing this and you will get a sequence of fractions that quickly squeeze the x.

It can be shown that no fraction with a smaller denominator can get closer than fractions in this sequence.

frac(3.14159265358979); sub frac { my ($x,$a,$b,$c,$d,$e,$f) = (@_,0,1,1,0,1,1); while ($f<1000) { if ($e<$x*$f) { ($a,$b) = ($e,$f) } else { ($c,$d) = ($e,$f) } ($e,$f) = ($a+$c, $b+$d); print "$a/$b < $x < $c/$d; => $e/$f\n"; } }
Produces the output
1/1 < 3.14159265358979 < 1/0; => 2/1 2/1 < 3.14159265358979 < 1/0; => 3/1 3/1 < 3.14159265358979 < 1/0; => 4/1 3/1 < 3.14159265358979 < 4/1; => 7/2 3/1 < 3.14159265358979 < 7/2; => 10/3 3/1 < 3.14159265358979 < 10/3; => 13/4 3/1 < 3.14159265358979 < 13/4; => 16/5 3/1 < 3.14159265358979 < 16/5; => 19/6 3/1 < 3.14159265358979 < 19/6; => 22/7 3/1 < 3.14159265358979 < 22/7; => 25/8 25/8 < 3.14159265358979 < 22/7; => 47/15 47/15 < 3.14159265358979 < 22/7; => 69/22 69/22 < 3.14159265358979 < 22/7; => 91/29 91/29 < 3.14159265358979 < 22/7; => 113/36 113/36 < 3.14159265358979 < 22/7; => 135/43 135/43 < 3.14159265358979 < 22/7; => 157/50 157/50 < 3.14159265358979 < 22/7; => 179/57 179/57 < 3.14159265358979 < 22/7; => 201/64 201/64 < 3.14159265358979 < 22/7; => 223/71 223/71 < 3.14159265358979 < 22/7; => 245/78 245/78 < 3.14159265358979 < 22/7; => 267/85 267/85 < 3.14159265358979 < 22/7; => 289/92 289/92 < 3.14159265358979 < 22/7; => 311/99 311/99 < 3.14159265358979 < 22/7; => 333/106 333/106 < 3.14159265358979 < 22/7; => 355/113 333/106 < 3.14159265358979 < 355/113; => 688/219 688/219 < 3.14159265358979 < 355/113; => 1043/332 1043/332 < 3.14159265358979 < 355/113; => 1398/445 1398/445 < 3.14159265358979 < 355/113; => 1753/558 1753/558 < 3.14159265358979 < 355/113; => 2108/671 2108/671 < 3.14159265358979 < 355/113; => 2463/784 2463/784 < 3.14159265358979 < 355/113; => 2818/897 2818/897 < 3.14159265358979 < 355/113; => 3173/1010