frac 0.9.2 → 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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