fraction 0.1

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.
Files changed (3) hide show
  1. data/extconf.rb +5 -0
  2. data/fraction.c +105 -0
  3. metadata +57 -0
@@ -0,0 +1,5 @@
1
+ require 'mkmf'
2
+ extension_name = 'fraction'
3
+
4
+ dir_config(extension_name)
5
+ create_makefile(extension_name)
@@ -0,0 +1,105 @@
1
+ /*
2
+ ** find rational approximation to given real number
3
+ ** David Eppstein / UC Irvine / 8 Aug 1993
4
+ **
5
+ ** With corrections from Arno Formella, May 2008
6
+ **
7
+ ** Made into a ruby module by Christopher Lord, Nov 2009
8
+ **
9
+ ** usage: require 'findfract'
10
+ **
11
+ ** n,d,err = 0.33.fraction
12
+ **
13
+ ** based on the theory of continued fractions
14
+ ** if x = a1 + 1/(a2 + 1/(a3 + 1/(a4 + ...)))
15
+ ** then best approximation is found by truncating this series
16
+ ** (with some adjustments in the last term).
17
+ **
18
+ ** Note the fraction can be recovered as the first column of the matrix
19
+ ** ( a1 1 ) ( a2 1 ) ( a3 1 ) ...
20
+ ** ( 1 0 ) ( 1 0 ) ( 1 0 )
21
+ ** Instead of keeping the sequence of continued fraction terms,
22
+ ** we just keep the last partial product of these matrices.
23
+ */
24
+
25
+ #include "ruby.h"
26
+ #include <stdio.h>
27
+ VALUE method_html_form_for(VALUE self)
28
+ {
29
+ VALUE res = rb_str_new2("<span class='fraction'><span class='above'>");
30
+ // This is an array. to make a string form, we want to
31
+ VALUE num = rb_obj_as_string(rb_ary_entry(self, 0));
32
+ VALUE den = rb_obj_as_string(rb_ary_entry(self, 1));
33
+ rb_str_concat(res, rb_obj_as_string(num));
34
+ rb_str_cat2(res, "</span>&#8260;<span class='below'>");
35
+ rb_str_concat(res, rb_obj_as_string(den));
36
+ rb_str_cat2(res, "</span></span>");
37
+ // CSS for the above html (From http://www.cs.tut.fi/~jkorpela/math/#fractions)
38
+ // .above, .below { font-size: 70%;
39
+ // font-family: Verdana, Arial, sans-serif; }
40
+ // .above { vertical-align: 0.7ex; }
41
+ // .below { vertical-align: -0.3ex; }
42
+ return res;
43
+ }
44
+ VALUE method_string_form_for(VALUE self)
45
+ {
46
+ VALUE res = rb_str_new2("");
47
+ // This is an array. to make a string form, we want to
48
+ VALUE num = rb_obj_as_string(rb_ary_entry(self, 0));
49
+ VALUE den = rb_obj_as_string(rb_ary_entry(self, 1));
50
+ rb_str_concat(res, rb_obj_as_string(num));
51
+ rb_str_cat2(res, "/");
52
+ rb_str_concat(res, rb_obj_as_string(den));
53
+ return res;
54
+ }
55
+ VALUE method_fraction_for(int argc, VALUE * argv, VALUE self)
56
+ {
57
+ long m11, m12,
58
+ m21, m22;
59
+ VALUE res = rb_ary_new2(3);
60
+ VALUE maxdenr;
61
+ int maxden = 10; // the default
62
+ rb_scan_args(argc, argv, "01", &maxdenr);
63
+ if (!NIL_P(maxdenr))
64
+ maxden = NUM2INT(maxdenr);
65
+ int ai;
66
+ double x = NUM2DBL(self);
67
+ double startx = x;
68
+ m11 = m22 = 1;
69
+ m12 = m21 = 0;
70
+
71
+ // loop finding terms until denom gets too big
72
+ while (m21 * ( ai = (long)x ) + m22 <= maxden) {
73
+ long t = m11 * ai + m12;
74
+ m12 = m11;
75
+ m11 = t;
76
+ t = m21 * ai + m22;
77
+ m22 = m21;
78
+ m21 = t;
79
+ if(x==(double)ai) break;
80
+ x = 1/(x - (double) ai);
81
+ if(x>(double)0x7FFFFFFF) break;
82
+ }
83
+ VALUE numer1 = INT2NUM(m11);
84
+ VALUE denom1 = INT2NUM(m21);
85
+ VALUE err1 = rb_float_new(startx - ((double) m11 / (double) m21));
86
+ rb_ary_store(res, 0, numer1);
87
+ rb_ary_store(res, 1, denom1);
88
+ rb_ary_store(res, 2, err1);
89
+ // rb_define_singleton_method(res, "to_s", method_string_form_for, 0);
90
+ // rb_define_singleton_method(res, "to_html", method_html_form_for, 0);
91
+
92
+
93
+ /* We can go one more step to find another candidate:
94
+ m11 = m11 * ai + m12;
95
+ m21 = m21 * ai + m22;
96
+ m11/m21, err= startx - ((double) m11 / (double) m21))
97
+ */
98
+ return res;
99
+ }
100
+
101
+ void Init_fraction() {
102
+ rb_define_method(rb_cNumeric, "fraction", method_fraction_for, -1);
103
+ rb_define_method(rb_cFloat, "fraction", method_fraction_for, -1);
104
+ }
105
+
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fraction
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.1"
5
+ platform: ruby
6
+ authors:
7
+ - Christopher Lord
8
+ - David Eppstein
9
+ - Arno Formella
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+
14
+ date: 2009-11-27 00:00:00 -05:00
15
+ default_executable:
16
+ dependencies: []
17
+
18
+ description: Provides a "fraction" method on all ruby floats.
19
+ email: christopherlord+fractiongem@gmail.com
20
+ executables: []
21
+
22
+ extensions:
23
+ - extconf.rb
24
+ extra_rdoc_files: []
25
+
26
+ files:
27
+ - fraction.c
28
+ has_rdoc: true
29
+ homepage: http://christopher.lord.ac
30
+ licenses: []
31
+
32
+ post_install_message:
33
+ rdoc_options: []
34
+
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: "0"
42
+ version:
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ version:
49
+ requirements: []
50
+
51
+ rubyforge_project:
52
+ rubygems_version: 1.3.5
53
+ signing_key:
54
+ specification_version: 3
55
+ summary: Provides a "fraction" method on all ruby floats.
56
+ test_files: []
57
+