ext_fraction 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4ed86dddf6d09e8de0bbab6119fdf4a6be93e08d5ad37bd089e770369238ca16
4
+ data.tar.gz: f3a0e34778bed346c3a8e2d0aa14afa8db5957f0ec9b108a2ac69b8c7291d06f
5
+ SHA512:
6
+ metadata.gz: 01cb5003dae715e05382a663a00e701e6c10df09318089375737320e509bc4ac7e02a94bbc4c801b1d31c3eaa011f3cf3d46fb6e284b36327e4004502c9ce95d
7
+ data.tar.gz: ba6ec1423db672cff5f63cb2947ef543ba4b612a84dcd58261e473f05f7067bb163cf77b181a525dade65e4ae6e89eea0a82efc347f9ecf117c22b8971141c99
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+
3
+ create_makefile("fraction/fraction")
@@ -0,0 +1,95 @@
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 'fraction'
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
+
28
+ static VALUE rb_cFraction;
29
+
30
+ void core_fraction(double val, long maxden, long * n, long * d, double * e)
31
+ {
32
+ int ai;
33
+ long sign = 1;
34
+ long m11 = 1, m22 = 1;
35
+ long m12 = 0, m21 = 0;
36
+ if (val < 0.0) {
37
+ // work in positive space, it seems we can get confused by negatives
38
+ sign = -1;
39
+ val *= -1.0;
40
+ }
41
+ double x = val;
42
+ long count = 0;
43
+
44
+ // loop finding terms until denom gets too big
45
+ while (m21 * ( ai = (long)x ) + m22 <= maxden) {
46
+ if (++count > 50000000) break; // break after 'too many' iterations
47
+ long t = m11 * ai + m12;
48
+ m12 = m11;
49
+ m11 = t;
50
+ t = m21 * ai + m22;
51
+ m22 = m21;
52
+ m21 = t;
53
+ if(x==(double)ai) break;
54
+ x = 1/(x - (double) ai);
55
+ if(x>(double)0x7FFFFFFF) break;
56
+ }
57
+ *n = m11 * sign;
58
+ *d = m21;
59
+ *e = val - ((double)m11 / (double)m21);
60
+ }
61
+
62
+ VALUE fraction_create_fraction_from(int argc, VALUE * argv, VALUE self)
63
+ {
64
+ VALUE fraction = rb_class_new_instance(0, NULL, rb_cFraction);
65
+
66
+ VALUE res = rb_ary_new2(3);
67
+ VALUE maxdenr;
68
+ long maxden = 10; // the default
69
+ rb_scan_args(argc, argv, "01", &maxdenr);
70
+ if (!NIL_P(maxdenr))
71
+ maxden = NUM2INT(maxdenr);
72
+ double x = NUM2DBL(self);
73
+ long n, d;
74
+ double e;
75
+ core_fraction(x, maxden, &n, &d, &e);
76
+
77
+ VALUE numer1 = INT2NUM(n);
78
+ VALUE denom1 = INT2NUM(d);
79
+ VALUE err1 = rb_float_new(e);
80
+
81
+ rb_iv_set(fraction, "@numerator", numer1);
82
+ rb_iv_set(fraction, "@denominator", denom1);
83
+ rb_iv_set(fraction, "@error", err1);
84
+
85
+ return fraction;
86
+ }
87
+
88
+ void Init_fraction() {
89
+
90
+ rb_cFraction = rb_define_class("Fraction", rb_cObject);
91
+
92
+ rb_define_method(rb_cNumeric, "to_fraction", fraction_create_fraction_from, -1);
93
+ rb_define_method(rb_cFloat, "to_fraction", fraction_create_fraction_from, -1);
94
+ }
95
+
@@ -0,0 +1 @@
1
+ require 'fraction'
@@ -0,0 +1,46 @@
1
+ require 'fraction/fraction'
2
+
3
+ class Fraction
4
+ attr_reader :numerator, :denominator, :error
5
+
6
+ def to_html
7
+ entity = case self.numerator
8
+
9
+ when 1 then
10
+ case self.denominator
11
+ when 2 then "&frac12;"
12
+ when 3 then "&#x2153;"
13
+ when 4 then "&frac14;"
14
+ when 5 then "&#x2155;"
15
+ when 6 then "&#x2159;"
16
+ when 8 then "&#x215B;"
17
+ end
18
+
19
+ when 2 then
20
+ case self.denominator
21
+ when 3 then "&#x2154;"
22
+ when 5 then "&#x2156;"
23
+ end
24
+
25
+ when 3 then
26
+ case self.denominator
27
+ when 4 then "&frac34;"
28
+ when 5 then "&#x2157;"
29
+ when 8 then "&#x215C;"
30
+ end
31
+
32
+ when 4 then "&#x2158;"
33
+
34
+ when 5 then
35
+ case self.denominator
36
+ when 6 then "&#x215A;"
37
+ when 8 then "&#x215D;"
38
+ end
39
+
40
+ when 7 then "&#x215E;"
41
+ end
42
+
43
+ entity ||= "#{self.numerator}/#{self.denominator}"
44
+ entity
45
+ end
46
+ end
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ext_fraction
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.2
5
+ platform: ruby
6
+ authors:
7
+ - Christopher Lord
8
+ - David Eppstein
9
+ - Arno Formella
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2020-08-19 00:00:00.000000000 Z
14
+ dependencies: []
15
+ description: Provides "to_fraction" and to_whole_fraction methods on all ruby floats
16
+ and numerics.
17
+ email: christopherlord+fractiongem@gmail.com
18
+ executables: []
19
+ extensions:
20
+ - ext/fraction/extconf.rb
21
+ extra_rdoc_files: []
22
+ files:
23
+ - ext/fraction/extconf.rb
24
+ - ext/fraction/fraction.c
25
+ - lib/ext_fraction.rb
26
+ - lib/fraction.rb
27
+ homepage: https://github.com/clord/fraction
28
+ licenses: []
29
+ metadata: {}
30
+ post_install_message:
31
+ rdoc_options: []
32
+ require_paths:
33
+ - lib
34
+ required_ruby_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ required_rubygems_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ requirements: []
45
+ rubygems_version: 3.0.3
46
+ signing_key:
47
+ specification_version: 4
48
+ summary: Provides a "to_fraction" method on all ruby floats.
49
+ test_files: []