ext_fraction 0.3.2

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.
@@ -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: []