[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

An extension to Rational - friendlier with Floats and Strings

Dave Burt

5/7/2005 3:43:00 PM

Hi,

Luke Galea asked a few days ago:
> I need to convert a float to a fraction.. So 1.5 to 1 1/2..
> The rational class would represent at least 3/2 well.. but I was surprised
> to
> find that there is no way to easily go from float to rational..
>
> Am I missing an easier way?

I borrowed a bunch of code from the Python Sourceforge CVS, because there is
a pretty decent Rational implementation there (that isn't in their standard
library yet, either) and tacked it onto Ruby's standard Rational.

http://www.dave.burt.id.au/ruby/ratio...
http://www.dave.burt.id.au/ruby/rational_e...

The first is the library - just require it, the base ('rational') is
standard and should already be there.
The second are some tests, good for an intro to how the library is used.

Here's an example of its use, mostly relevant to Luke's query:

require 'rational_ext'
"3/2".to_r #=> Rational(3, 2)
"1.5".to_r #=> Rational(3, 2)
1.5.to_r.approximate #=> Rational(3, 2)
1.5.to_r #=> Rational(3, 2) # power-of-2 fractions make nice Floats
1.6.to_r #=> Rational(3602879701896397, 2251799813685248)
1.6.to_r.approximate #=> Rational(8, 5)

Here's more about the library extension:

Includes conversions from String and Float, inversion, reduction methods
(trim and approximate), and a to_s with a base conversion parameter.

A bunch of this code is taken from the Python project:
http://cvs.sourceforge.net/viewcvs.py/python/python/nondi...
/rational/Rational.py?rev=1.3&view=markup

Methods replaced:

Rational(n, d = 1) # replaced - now accepts Floats and Strings
# like Rational(1.3e15) or Rational("4/5")

Rational::to_s(n = 10) # replaced - now accepts a radix
Rational::to_f # replaced - doesn't return NaN any more
Rational::hash # replaced - r.hash==r.to_i.hash if r==r.to_i

Methods added:

Rational::trim(max_d) # simplify approximately, set max denominator
Rational::approximate(err = 1e-12) # simplify approximately, within +/-err
Rational::inv # invert

Float::to_r # converts to Rational, exactly
String::to_r # converts to Rational if possible, or returns Rational(0)

Cheers,
Dave