use strict; use warnings; while () { chomp; my ($den, $div, $error) = fraction($_); print "$_\t$den/$div\n"; } sub fraction { my $value = shift; my $a = 1; my $b = int(1 / $value); my $c = (1 / $b) - $value; # error return ($a, $b, $c) if $c < 0.0005; my ($d, $e, $f) = fraction($c); my $g = $a * $e - $d * $b; my $h = $b * $e; for (2,3,5,7) { # reduces 2/4 => 1/2, 3/27 => 1/9, etc. ($g, $h) = reduce($g, $h, $_); } return ($g, $h, $f); } sub reduce { my ($a, $b, $base) = @_; while ($a % $base == 0 && $b % $base == 0) { $a = $a / $base; $b = $b / $base; } return ($a, $b); } __DATA__ 0.035 0.037 0.039 0.041 0.043 0.046 0.048 0.058 0.068 0.078 0.35 0.37 0.39 0.41 0.43 0.46 0.48 0.58 0.68 0.78