Thanks for all the great responses! So.. I guess the next question is: Does everyone think this is a worthwhile addition to the Ruby STDLib?If so, how do we go about getting it added to Rational.rb? On Thursday 05 May 2005 17:27, Mark Hubbart wrote: > On 5/5/05, Christoph <chr_mail / gmx.net> wrote: > > Zane Dodson schrieb: > > >Knuth has a discussion of this in `Seminumerical Algorithms, The Art > > >of Computer Programming, vol. 2.' > > > > > >In the third edition, it is in sec. 4.5.3 (pp. 356ff). See also > > >exercise 4.5.3.2 > > > > Florian's solution is of course nothing but continued fraction > > - without the (relative) error term he could be into a long wait > > calling #to_r unless he is very lucky .. > > Thanks to those who mentioned the "continued fractions" method. Here's > a new implementation: > > ---- > require 'mathn' > > class Numeric > def inverse > 1/self > end > end > > class Float > > def to_r > n = 1 > n *= 2 until (self*n) % 1 == 0 > (self*n).to_i/n > end > > def round_to_r > return self.to_i if self % 1 == 0 > n = self > ops = [] > count = 0 > until ((n%1).round - n%1).abs < 1e-8 || count > 20 || > n.abs == 1.0/0.0 || n == 0.0/0.0 > int, dec = n.divmod 1 > ops.concat [[:+, int.to_i], [:inverse]] > n = 1/dec > count += 1 > end > n = n.round > ops.reverse.inject(n.round){|n, op| n.send(*op)} > end > end > ---- > > Use Float#to_r for an exact representation of the float value, or > Float#round_to_r for an extremely close representation of it. > > cheers, > Mark