frac 0.9.2 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,33 @@
1
+ = Find rational approximation to given real number
2
+
3
+ Convert Float to Rational with given denominator maximum
4
+
5
+ Math.frac(0.2, 100) # => (1/5)
6
+ Math.frac(0.33, 10) # => (1/3)
7
+ Math.frac(0.33, 100) # => (33/100)
8
+
9
+ == Differe from ruby 1.9 build-in Float#to_r
10
+
11
+ # Build-in
12
+ 1.1.to_r # => (2476979795053773/2251799813685248)
13
+ # Math#frac with big max denominator
14
+ Math.frac(1.1, 1_000_000_000) # => (11/10)
15
+
16
+ == Source
17
+
18
+ Idea and most implementation from http://www.ics.uci.edu/~eppstein/numth/frap.c
19
+
20
+ Based on the theory of continued fractions
21
+
22
+ if x = a1 + 1/(a2 + 1/(a3 + 1/(a4 + ...)))
23
+
24
+ then best approximation is found by truncating this series
25
+ (with some adjustments in the last term).
26
+
27
+ Note the fraction can be recovered as the first column of the matrix
28
+
29
+ ( a1 1 ) ( a2 1 ) ( a3 1 ) ...
30
+ ( 1 0 ) ( 1 0 ) ( 1 0 )
31
+
32
+ Instead of keeping the sequence of continued fraction terms,
33
+ we just keep the last partial product of these matrices.
data/ext/frac_ext.c CHANGED
@@ -35,6 +35,9 @@ static VALUE find_fracs(VALUE mod, VALUE rv, VALUE dv)
35
35
  double startx, x = RFLOAT_VALUE(rv);
36
36
  long ai, maxden = NUM2LONG(dv);
37
37
 
38
+ if (maxden <= 0)
39
+ rb_raise(rb_eArgError, "maximum denominator should be > 0");
40
+
38
41
  startx = x;
39
42
 
40
43
  /* initialize matrix */
data/lib/frac.rb CHANGED
@@ -1,10 +1,15 @@
1
1
 
2
+ require 'rational'
2
3
  require 'frac_ext'
3
4
 
4
5
  module Math
5
- # Find rational approximation to given real number.
6
- def self.frac(float, prec)
7
- arr = find_fracs(float, prec)
8
- arr[2].abs > arr[5].abs ? Rational(arr[3], arr[4]) : Rational(arr[0], arr[1])
6
+ class << self
7
+ private :find_fracs
8
+
9
+ # Find rational approximation to given real number.
10
+ def frac(float, maxden)
11
+ arr = find_fracs(Float(float), Integer(maxden))
12
+ arr[2].abs > arr[5].abs ? Rational(arr[3], arr[4]) : Rational(arr[0], arr[1])
13
+ end
9
14
  end
10
15
  end
data/test/frac_test.rb ADDED
@@ -0,0 +1,33 @@
1
+ require 'test/unit'
2
+ require File.join(File.dirname(__FILE__), %w{.. lib frac})
3
+
4
+ class TC_Frac < Test::Unit::TestCase
5
+ def test_frac
6
+ [[ 0.333, 1, 3, 0x100],
7
+ [ 0.77, 77, 100, 0x100],
8
+ [ 0.2, 1, 5, 0x100],
9
+ [ 2, 2, 1, 0x100],
10
+ [-0.5, -1, 2, 0x100],
11
+ [ 0, 0, 1, 0x100],
12
+ ["0.85",17, 20, 0x100],
13
+ [ 0.5, 1, 2, '1000'],
14
+ [ 0.001, 0, 1, 2]
15
+ ].each{|float, num, den, prec|
16
+ assert_equal Rational(num, den), Math.frac(float, prec), "#{float.inspect} -> #{num} / #{den}"
17
+ }
18
+ end
19
+
20
+ def test_access
21
+ assert_raise NoMethodError do
22
+ Math.find_fracs 0.1, 0x100
23
+ end
24
+ end
25
+
26
+ def test_validation
27
+ [[1.1, ''], [nil, 0x100], [1.1, 0], [1.5, -100]].each{|params|
28
+ assert_raise ArgumentError, TypeError do
29
+ Math.frac(*params)
30
+ end
31
+ }
32
+ end
33
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 9
8
- - 2
9
- version: 0.9.2
8
+ - 3
9
+ version: 0.9.3
10
10
  platform: ruby
11
11
  authors:
12
12
  - Pavel Valodzka
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-25 00:00:00 +03:00
17
+ date: 2010-05-26 00:00:00 +03:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
@@ -30,6 +30,8 @@ files:
30
30
  - ext/frac_ext.c
31
31
  - ext/extconf.rb
32
32
  - lib/frac.rb
33
+ - test/frac_test.rb
34
+ - README.rdoc
33
35
  has_rdoc: true
34
36
  homepage: http://github.com/valodzka/frac
35
37
  licenses: []
@@ -59,6 +61,6 @@ rubyforge_project:
59
61
  rubygems_version: 1.3.6
60
62
  signing_key:
61
63
  specification_version: 2
62
- summary: Find rational approximation to given real number. based on the theory of continued fractions if x = a1 + 1/(a2 + 1/(a3 + 1/(a4 + ...))) then best approximation is found by truncating this series (with some adjustments in the last term). Note the fraction can be recovered as the first column of the matrix ( a1 1 ) ( a2 1 ) ( a3 1 ) ... ( 1 0 ) ( 1 0 ) ( 1 0 ) Instead of keeping the sequence of continued fraction terms, we just keep the last partial product of these matrices.
64
+ summary: Find rational approximation to given real number. Based on the theory of continued fractions if x = a1 + 1/(a2 + 1/(a3 + 1/(a4 + ...))) then best approximation is found by truncating this series (with some adjustments in the last term). Note the fraction can be recovered as the first column of the matrix ( a1 1 ) ( a2 1 ) ( a3 1 ) ... ( 1 0 ) ( 1 0 ) ( 1 0 ) Instead of keeping the sequence of continued fraction terms, we just keep the last partial product of these matrices.
63
65
  test_files: []
64
66