#!/usr/bin/env perl use strict; use warnings; use Math::BigRat; use Math::Trig; my $x = abs(Math::BigRat->new(-1/3)); print "$x\n"; for my $s(0..6) { my $pi = ratFromFloatSteps($s, pi); print "$s -> $pi\n"; } my $pi = ratFromFloatEpsilon(0.000001, pi); print " $pi\n"; sub ratFromFloatEpsilon { my ($epsilon, $inp) = @_; my $steps = 0; my $old = ratFromFloatSteps($steps, $inp); for(;;) { $steps++; my $n = ratFromFloatSteps($steps, $inp); if(abs($old-$n) < $epsilon) { return $n } else { $old = $n } } } sub ratFromFloatSteps { my ($steps, $inp) = @_; #print " [[ $steps $inp ]]\n"; if($inp < 0) { return ratFromFloatSteps($steps, -$inp) } if(0 == $inp) { return Math::BigRat->new(0) } if($steps <= 0) { return Math::BigRat->new(int $inp); } my $prop = int $inp; my $rem = $inp - $prop; $prop = Math::BigRat->new($prop); $rem = 1/ratFromFloatSteps($steps-1, 1/$rem); return $prop + $rem; }