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 +33 -0
- data/ext/frac_ext.c +3 -0
- data/lib/frac.rb +9 -4
- data/test/frac_test.rb +33 -0
- metadata +6 -4
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
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
-
-
|
9
|
-
version: 0.9.
|
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-
|
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.
|
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
|
|