An extension to Rational - friendlier with Floats and Strings

D

Dave Burt

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/rational_ext.rb
http://www.dave.burt.id.au/ruby/rational_ext_test.rb

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/nondist/sandbox
/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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top