bigdecimal 3.1.4-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e9fced8ced07121aeb95b8d3d0dfe0a341025ffda5382115e50b2f2e247b4cc5
4
+ data.tar.gz: eb74b46e55565a8d7d0669bf7bf42824498be32d3e0c514378b65d399b84cff3
5
+ SHA512:
6
+ metadata.gz: e343e759448c7e3d25fa27557f7ee791e2269e8146813ece216da77923474be65407381aca04ba42f59795001058e38ff3efd7ed01c93e04f44824d6781ddc54
7
+ data.tar.gz: 211ca130d2b9cf5677eee155d4ef56d8483f60eb15855dfdbc65a0cdf343238efdcb8d66ef2d1e6d82111434e00c7283380dd2c5e29c27c0fcad0706396eb817
@@ -0,0 +1,54 @@
1
+ # coding: utf-8
2
+
3
+ name = File.basename(__FILE__, '.*')
4
+ source_version = ["", "ext/#{name}/"].find do |dir|
5
+ begin
6
+ break File.foreach(File.join(__dir__, "#{dir}#{name}.c")) {|line|
7
+ break $1.sub("-", ".") if /^#define\s+#{name.upcase}_VERSION\s+"(.+)"/o =~ line
8
+ }
9
+ rescue Errno::ENOENT
10
+ end
11
+ end or raise "can't find #{name.upcase}_VERSION"
12
+
13
+ Gem::Specification.new do |s|
14
+ s.name = name
15
+ s.version = source_version
16
+ s.authors = ["Kenta Murata", "Zachary Scott", "Shigeo Kobayashi"]
17
+ s.email = ["mrkn@mrkn.jp"]
18
+
19
+ s.summary = "Arbitrary-precision decimal floating-point number library."
20
+ s.description = "This library provides arbitrary-precision decimal floating-point number class."
21
+ s.homepage = "https://github.com/ruby/bigdecimal"
22
+ s.licenses = ["Ruby", "BSD-2-Clause"]
23
+
24
+ s.require_paths = %w[lib]
25
+ s.files = %w[
26
+ bigdecimal.gemspec
27
+ lib/bigdecimal.rb
28
+ lib/bigdecimal/jacobian.rb
29
+ lib/bigdecimal/ludcmp.rb
30
+ lib/bigdecimal/math.rb
31
+ lib/bigdecimal/newton.rb
32
+ lib/bigdecimal/util.rb
33
+ sample/linear.rb
34
+ sample/nlsolve.rb
35
+ sample/pi.rb
36
+ ]
37
+ if Gem::Platform === s.platform and s.platform =~ 'java' or RUBY_ENGINE == 'jruby'
38
+ s.platform = 'java'
39
+ else
40
+ s.extensions = %w[ext/bigdecimal/extconf.rb]
41
+ s.files += %w[
42
+ ext/bigdecimal/bigdecimal.c
43
+ ext/bigdecimal/bigdecimal.h
44
+ ext/bigdecimal/bits.h
45
+ ext/bigdecimal/feature.h
46
+ ext/bigdecimal/missing.c
47
+ ext/bigdecimal/missing.h
48
+ ext/bigdecimal/missing/dtoa.c
49
+ ext/bigdecimal/static_assert.h
50
+ ]
51
+ end
52
+
53
+ s.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
54
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: false
2
+
3
+ require 'bigdecimal'
4
+
5
+ # require 'bigdecimal/jacobian'
6
+ #
7
+ # Provides methods to compute the Jacobian matrix of a set of equations at a
8
+ # point x. In the methods below:
9
+ #
10
+ # f is an Object which is used to compute the Jacobian matrix of the equations.
11
+ # It must provide the following methods:
12
+ #
13
+ # f.values(x):: returns the values of all functions at x
14
+ #
15
+ # f.zero:: returns 0.0
16
+ # f.one:: returns 1.0
17
+ # f.two:: returns 2.0
18
+ # f.ten:: returns 10.0
19
+ #
20
+ # f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal.
21
+ #
22
+ # x is the point at which to compute the Jacobian.
23
+ #
24
+ # fx is f.values(x).
25
+ #
26
+ module Jacobian
27
+ module_function
28
+
29
+ # Determines the equality of two numbers by comparing to zero, or using the epsilon value
30
+ def isEqual(a,b,zero=0.0,e=1.0e-8)
31
+ aa = a.abs
32
+ bb = b.abs
33
+ if aa == zero && bb == zero then
34
+ true
35
+ else
36
+ if ((a-b)/(aa+bb)).abs < e then
37
+ true
38
+ else
39
+ false
40
+ end
41
+ end
42
+ end
43
+
44
+
45
+ # Computes the derivative of +f[i]+ at +x[i]+.
46
+ # +fx+ is the value of +f+ at +x+.
47
+ def dfdxi(f,fx,x,i)
48
+ nRetry = 0
49
+ n = x.size
50
+ xSave = x[i]
51
+ ok = 0
52
+ ratio = f.ten*f.ten*f.ten
53
+ dx = x[i].abs/ratio
54
+ dx = fx[i].abs/ratio if isEqual(dx,f.zero,f.zero,f.eps)
55
+ dx = f.one/f.ten if isEqual(dx,f.zero,f.zero,f.eps)
56
+ until ok>0 do
57
+ deriv = []
58
+ nRetry += 1
59
+ if nRetry > 100
60
+ raise "Singular Jacobian matrix. No change at x[" + i.to_s + "]"
61
+ end
62
+ dx = dx*f.two
63
+ x[i] += dx
64
+ fxNew = f.values(x)
65
+ for j in 0...n do
66
+ if !isEqual(fxNew[j],fx[j],f.zero,f.eps) then
67
+ ok += 1
68
+ deriv <<= (fxNew[j]-fx[j])/dx
69
+ else
70
+ deriv <<= f.zero
71
+ end
72
+ end
73
+ x[i] = xSave
74
+ end
75
+ deriv
76
+ end
77
+
78
+ # Computes the Jacobian of +f+ at +x+. +fx+ is the value of +f+ at +x+.
79
+ def jacobian(f,fx,x)
80
+ n = x.size
81
+ dfdx = Array.new(n*n)
82
+ for i in 0...n do
83
+ df = dfdxi(f,fx,x,i)
84
+ for j in 0...n do
85
+ dfdx[j*n+i] = df[j]
86
+ end
87
+ end
88
+ dfdx
89
+ end
90
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: false
2
+ require 'bigdecimal'
3
+
4
+ #
5
+ # Solves a*x = b for x, using LU decomposition.
6
+ #
7
+ module LUSolve
8
+ module_function
9
+
10
+ # Performs LU decomposition of the n by n matrix a.
11
+ def ludecomp(a,n,zero=0,one=1)
12
+ prec = BigDecimal.limit(nil)
13
+ ps = []
14
+ scales = []
15
+ for i in 0...n do # pick up largest(abs. val.) element in each row.
16
+ ps <<= i
17
+ nrmrow = zero
18
+ ixn = i*n
19
+ for j in 0...n do
20
+ biggst = a[ixn+j].abs
21
+ nrmrow = biggst if biggst>nrmrow
22
+ end
23
+ if nrmrow>zero then
24
+ scales <<= one.div(nrmrow,prec)
25
+ else
26
+ raise "Singular matrix"
27
+ end
28
+ end
29
+ n1 = n - 1
30
+ for k in 0...n1 do # Gaussian elimination with partial pivoting.
31
+ biggst = zero;
32
+ for i in k...n do
33
+ size = a[ps[i]*n+k].abs*scales[ps[i]]
34
+ if size>biggst then
35
+ biggst = size
36
+ pividx = i
37
+ end
38
+ end
39
+ raise "Singular matrix" if biggst<=zero
40
+ if pividx!=k then
41
+ j = ps[k]
42
+ ps[k] = ps[pividx]
43
+ ps[pividx] = j
44
+ end
45
+ pivot = a[ps[k]*n+k]
46
+ for i in (k+1)...n do
47
+ psin = ps[i]*n
48
+ a[psin+k] = mult = a[psin+k].div(pivot,prec)
49
+ if mult!=zero then
50
+ pskn = ps[k]*n
51
+ for j in (k+1)...n do
52
+ a[psin+j] -= mult.mult(a[pskn+j],prec)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ raise "Singular matrix" if a[ps[n1]*n+n1] == zero
58
+ ps
59
+ end
60
+
61
+ # Solves a*x = b for x, using LU decomposition.
62
+ #
63
+ # a is a matrix, b is a constant vector, x is the solution vector.
64
+ #
65
+ # ps is the pivot, a vector which indicates the permutation of rows performed
66
+ # during LU decomposition.
67
+ def lusolve(a,b,ps,zero=0.0)
68
+ prec = BigDecimal.limit(nil)
69
+ n = ps.size
70
+ x = []
71
+ for i in 0...n do
72
+ dot = zero
73
+ psin = ps[i]*n
74
+ for j in 0...i do
75
+ dot = a[psin+j].mult(x[j],prec) + dot
76
+ end
77
+ x <<= b[ps[i]] - dot
78
+ end
79
+ (n-1).downto(0) do |i|
80
+ dot = zero
81
+ psin = ps[i]*n
82
+ for j in (i+1)...n do
83
+ dot = a[psin+j].mult(x[j],prec) + dot
84
+ end
85
+ x[i] = (x[i]-dot).div(a[psin+i],prec)
86
+ end
87
+ x
88
+ end
89
+ end
@@ -0,0 +1,232 @@
1
+ # frozen_string_literal: false
2
+ require 'bigdecimal'
3
+
4
+ #
5
+ #--
6
+ # Contents:
7
+ # sqrt(x, prec)
8
+ # sin (x, prec)
9
+ # cos (x, prec)
10
+ # atan(x, prec) Note: |x|<1, x=0.9999 may not converge.
11
+ # PI (prec)
12
+ # E (prec) == exp(1.0,prec)
13
+ #
14
+ # where:
15
+ # x ... BigDecimal number to be computed.
16
+ # |x| must be small enough to get convergence.
17
+ # prec ... Number of digits to be obtained.
18
+ #++
19
+ #
20
+ # Provides mathematical functions.
21
+ #
22
+ # Example:
23
+ #
24
+ # require "bigdecimal/math"
25
+ #
26
+ # include BigMath
27
+ #
28
+ # a = BigDecimal((PI(100)/2).to_s)
29
+ # puts sin(a,100) # => 0.99999999999999999999......e0
30
+ #
31
+ module BigMath
32
+ module_function
33
+
34
+ # call-seq:
35
+ # sqrt(decimal, numeric) -> BigDecimal
36
+ #
37
+ # Computes the square root of +decimal+ to the specified number of digits of
38
+ # precision, +numeric+.
39
+ #
40
+ # BigMath.sqrt(BigDecimal('2'), 16).to_s
41
+ # #=> "0.1414213562373095048801688724e1"
42
+ #
43
+ def sqrt(x, prec)
44
+ x.sqrt(prec)
45
+ end
46
+
47
+ # call-seq:
48
+ # sin(decimal, numeric) -> BigDecimal
49
+ #
50
+ # Computes the sine of +decimal+ to the specified number of digits of
51
+ # precision, +numeric+.
52
+ #
53
+ # If +decimal+ is Infinity or NaN, returns NaN.
54
+ #
55
+ # BigMath.sin(BigMath.PI(5)/4, 5).to_s
56
+ # #=> "0.70710678118654752440082036563292800375e0"
57
+ #
58
+ def sin(x, prec)
59
+ raise ArgumentError, "Zero or negative precision for sin" if prec <= 0
60
+ return BigDecimal("NaN") if x.infinite? || x.nan?
61
+ n = prec + BigDecimal.double_fig
62
+ one = BigDecimal("1")
63
+ two = BigDecimal("2")
64
+ x = -x if neg = x < 0
65
+ if x > (twopi = two * BigMath.PI(prec))
66
+ if x > 30
67
+ x %= twopi
68
+ else
69
+ x -= twopi while x > twopi
70
+ end
71
+ end
72
+ x1 = x
73
+ x2 = x.mult(x,n)
74
+ sign = 1
75
+ y = x
76
+ d = y
77
+ i = one
78
+ z = one
79
+ while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
80
+ m = BigDecimal.double_fig if m < BigDecimal.double_fig
81
+ sign = -sign
82
+ x1 = x2.mult(x1,n)
83
+ i += two
84
+ z *= (i-one) * i
85
+ d = sign * x1.div(z,m)
86
+ y += d
87
+ end
88
+ neg ? -y : y
89
+ end
90
+
91
+ # call-seq:
92
+ # cos(decimal, numeric) -> BigDecimal
93
+ #
94
+ # Computes the cosine of +decimal+ to the specified number of digits of
95
+ # precision, +numeric+.
96
+ #
97
+ # If +decimal+ is Infinity or NaN, returns NaN.
98
+ #
99
+ # BigMath.cos(BigMath.PI(4), 16).to_s
100
+ # #=> "-0.999999999999999999999999999999856613163740061349e0"
101
+ #
102
+ def cos(x, prec)
103
+ raise ArgumentError, "Zero or negative precision for cos" if prec <= 0
104
+ return BigDecimal("NaN") if x.infinite? || x.nan?
105
+ n = prec + BigDecimal.double_fig
106
+ one = BigDecimal("1")
107
+ two = BigDecimal("2")
108
+ x = -x if x < 0
109
+ if x > (twopi = two * BigMath.PI(prec))
110
+ if x > 30
111
+ x %= twopi
112
+ else
113
+ x -= twopi while x > twopi
114
+ end
115
+ end
116
+ x1 = one
117
+ x2 = x.mult(x,n)
118
+ sign = 1
119
+ y = one
120
+ d = y
121
+ i = BigDecimal("0")
122
+ z = one
123
+ while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
124
+ m = BigDecimal.double_fig if m < BigDecimal.double_fig
125
+ sign = -sign
126
+ x1 = x2.mult(x1,n)
127
+ i += two
128
+ z *= (i-one) * i
129
+ d = sign * x1.div(z,m)
130
+ y += d
131
+ end
132
+ y
133
+ end
134
+
135
+ # call-seq:
136
+ # atan(decimal, numeric) -> BigDecimal
137
+ #
138
+ # Computes the arctangent of +decimal+ to the specified number of digits of
139
+ # precision, +numeric+.
140
+ #
141
+ # If +decimal+ is NaN, returns NaN.
142
+ #
143
+ # BigMath.atan(BigDecimal('-1'), 16).to_s
144
+ # #=> "-0.785398163397448309615660845819878471907514682065e0"
145
+ #
146
+ def atan(x, prec)
147
+ raise ArgumentError, "Zero or negative precision for atan" if prec <= 0
148
+ return BigDecimal("NaN") if x.nan?
149
+ pi = PI(prec)
150
+ x = -x if neg = x < 0
151
+ return pi.div(neg ? -2 : 2, prec) if x.infinite?
152
+ return pi / (neg ? -4 : 4) if x.round(prec) == 1
153
+ x = BigDecimal("1").div(x, prec) if inv = x > 1
154
+ x = (-1 + sqrt(1 + x**2, prec))/x if dbl = x > 0.5
155
+ n = prec + BigDecimal.double_fig
156
+ y = x
157
+ d = y
158
+ t = x
159
+ r = BigDecimal("3")
160
+ x2 = x.mult(x,n)
161
+ while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
162
+ m = BigDecimal.double_fig if m < BigDecimal.double_fig
163
+ t = -t.mult(x2,n)
164
+ d = t.div(r,m)
165
+ y += d
166
+ r += 2
167
+ end
168
+ y *= 2 if dbl
169
+ y = pi / 2 - y if inv
170
+ y = -y if neg
171
+ y
172
+ end
173
+
174
+ # call-seq:
175
+ # PI(numeric) -> BigDecimal
176
+ #
177
+ # Computes the value of pi to the specified number of digits of precision,
178
+ # +numeric+.
179
+ #
180
+ # BigMath.PI(10).to_s
181
+ # #=> "0.3141592653589793238462643388813853786957412e1"
182
+ #
183
+ def PI(prec)
184
+ raise ArgumentError, "Zero or negative precision for PI" if prec <= 0
185
+ n = prec + BigDecimal.double_fig
186
+ zero = BigDecimal("0")
187
+ one = BigDecimal("1")
188
+ two = BigDecimal("2")
189
+
190
+ m25 = BigDecimal("-0.04")
191
+ m57121 = BigDecimal("-57121")
192
+
193
+ pi = zero
194
+
195
+ d = one
196
+ k = one
197
+ t = BigDecimal("-80")
198
+ while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0)
199
+ m = BigDecimal.double_fig if m < BigDecimal.double_fig
200
+ t = t*m25
201
+ d = t.div(k,m)
202
+ k = k+two
203
+ pi = pi + d
204
+ end
205
+
206
+ d = one
207
+ k = one
208
+ t = BigDecimal("956")
209
+ while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0)
210
+ m = BigDecimal.double_fig if m < BigDecimal.double_fig
211
+ t = t.div(m57121,n)
212
+ d = t.div(k,m)
213
+ pi = pi + d
214
+ k = k+two
215
+ end
216
+ pi
217
+ end
218
+
219
+ # call-seq:
220
+ # E(numeric) -> BigDecimal
221
+ #
222
+ # Computes e (the base of natural logarithms) to the specified number of
223
+ # digits of precision, +numeric+.
224
+ #
225
+ # BigMath.E(10).to_s
226
+ # #=> "0.271828182845904523536028752390026306410273e1"
227
+ #
228
+ def E(prec)
229
+ raise ArgumentError, "Zero or negative precision for E" if prec <= 0
230
+ BigMath.exp(1, prec)
231
+ end
232
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: false
2
+ require "bigdecimal/ludcmp"
3
+ require "bigdecimal/jacobian"
4
+
5
+ #
6
+ # newton.rb
7
+ #
8
+ # Solves the nonlinear algebraic equation system f = 0 by Newton's method.
9
+ # This program is not dependent on BigDecimal.
10
+ #
11
+ # To call:
12
+ # n = nlsolve(f,x)
13
+ # where n is the number of iterations required,
14
+ # x is the initial value vector
15
+ # f is an Object which is used to compute the values of the equations to be solved.
16
+ # It must provide the following methods:
17
+ #
18
+ # f.values(x):: returns the values of all functions at x
19
+ #
20
+ # f.zero:: returns 0.0
21
+ # f.one:: returns 1.0
22
+ # f.two:: returns 2.0
23
+ # f.ten:: returns 10.0
24
+ #
25
+ # f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal.
26
+ #
27
+ # On exit, x is the solution vector.
28
+ #
29
+ module Newton
30
+ include LUSolve
31
+ include Jacobian
32
+ module_function
33
+
34
+ def norm(fv,zero=0.0) # :nodoc:
35
+ s = zero
36
+ n = fv.size
37
+ for i in 0...n do
38
+ s += fv[i]*fv[i]
39
+ end
40
+ s
41
+ end
42
+
43
+ # See also Newton
44
+ def nlsolve(f,x)
45
+ nRetry = 0
46
+ n = x.size
47
+
48
+ f0 = f.values(x)
49
+ zero = f.zero
50
+ one = f.one
51
+ two = f.two
52
+ p5 = one/two
53
+ d = norm(f0,zero)
54
+ minfact = f.ten*f.ten*f.ten
55
+ minfact = one/minfact
56
+ e = f.eps
57
+ while d >= e do
58
+ nRetry += 1
59
+ # Not yet converged. => Compute Jacobian matrix
60
+ dfdx = jacobian(f,f0,x)
61
+ # Solve dfdx*dx = -f0 to estimate dx
62
+ dx = lusolve(dfdx,f0,ludecomp(dfdx,n,zero,one),zero)
63
+ fact = two
64
+ xs = x.dup
65
+ begin
66
+ fact *= p5
67
+ if fact < minfact then
68
+ raise "Failed to reduce function values."
69
+ end
70
+ for i in 0...n do
71
+ x[i] = xs[i] - dx[i]*fact
72
+ end
73
+ f0 = f.values(x)
74
+ dn = norm(f0,zero)
75
+ end while(dn>=d)
76
+ d = dn
77
+ end
78
+ nRetry
79
+ end
80
+ end
@@ -0,0 +1,185 @@
1
+ # frozen_string_literal: false
2
+ #
3
+ #--
4
+ # bigdecimal/util extends various native classes to provide the #to_d method,
5
+ # and provides BigDecimal#to_d and BigDecimal#to_digits.
6
+ #++
7
+
8
+ require 'bigdecimal'
9
+
10
+ class Integer < Numeric
11
+ # call-seq:
12
+ # int.to_d -> bigdecimal
13
+ #
14
+ # Returns the value of +int+ as a BigDecimal.
15
+ #
16
+ # require 'bigdecimal'
17
+ # require 'bigdecimal/util'
18
+ #
19
+ # 42.to_d # => 0.42e2
20
+ #
21
+ # See also BigDecimal::new.
22
+ #
23
+ def to_d
24
+ BigDecimal(self)
25
+ end
26
+ end
27
+
28
+
29
+ class Float < Numeric
30
+ # call-seq:
31
+ # float.to_d -> bigdecimal
32
+ # float.to_d(precision) -> bigdecimal
33
+ #
34
+ # Returns the value of +float+ as a BigDecimal.
35
+ # The +precision+ parameter is used to determine the number of
36
+ # significant digits for the result. When +precision+ is set to +0+,
37
+ # the number of digits to represent the float being converted is determined
38
+ # automatically.
39
+ # The default +precision+ is +0+.
40
+ #
41
+ # require 'bigdecimal'
42
+ # require 'bigdecimal/util'
43
+ #
44
+ # 0.5.to_d # => 0.5e0
45
+ # 1.234.to_d # => 0.1234e1
46
+ # 1.234.to_d(2) # => 0.12e1
47
+ #
48
+ # See also BigDecimal::new.
49
+ #
50
+ def to_d(precision=0)
51
+ BigDecimal(self, precision)
52
+ end
53
+ end
54
+
55
+
56
+ class String
57
+ # call-seq:
58
+ # str.to_d -> bigdecimal
59
+ #
60
+ # Returns the result of interpreting leading characters in +str+
61
+ # as a BigDecimal.
62
+ #
63
+ # require 'bigdecimal'
64
+ # require 'bigdecimal/util'
65
+ #
66
+ # "0.5".to_d # => 0.5e0
67
+ # "123.45e1".to_d # => 0.12345e4
68
+ # "45.67 degrees".to_d # => 0.4567e2
69
+ #
70
+ # See also BigDecimal::new.
71
+ #
72
+ def to_d
73
+ BigDecimal.interpret_loosely(self)
74
+ end
75
+ end
76
+
77
+
78
+ class BigDecimal < Numeric
79
+ # call-seq:
80
+ # a.to_digits -> string
81
+ #
82
+ # Converts a BigDecimal to a String of the form "nnnnnn.mmm".
83
+ # This method is deprecated; use BigDecimal#to_s("F") instead.
84
+ #
85
+ # require 'bigdecimal/util'
86
+ #
87
+ # d = BigDecimal("3.14")
88
+ # d.to_digits # => "3.14"
89
+ #
90
+ def to_digits
91
+ if self.nan? || self.infinite? || self.zero?
92
+ self.to_s
93
+ else
94
+ i = self.to_i.to_s
95
+ _,f,_,z = self.frac.split
96
+ i + "." + ("0"*(-z)) + f
97
+ end
98
+ end
99
+
100
+ # call-seq:
101
+ # a.to_d -> bigdecimal
102
+ #
103
+ # Returns self.
104
+ #
105
+ # require 'bigdecimal/util'
106
+ #
107
+ # d = BigDecimal("3.14")
108
+ # d.to_d # => 0.314e1
109
+ #
110
+ def to_d
111
+ self
112
+ end
113
+ end
114
+
115
+
116
+ class Rational < Numeric
117
+ # call-seq:
118
+ # rat.to_d(precision) -> bigdecimal
119
+ #
120
+ # Returns the value as a BigDecimal.
121
+ #
122
+ # The required +precision+ parameter is used to determine the number of
123
+ # significant digits for the result.
124
+ #
125
+ # require 'bigdecimal'
126
+ # require 'bigdecimal/util'
127
+ #
128
+ # Rational(22, 7).to_d(3) # => 0.314e1
129
+ #
130
+ # See also BigDecimal::new.
131
+ #
132
+ def to_d(precision)
133
+ BigDecimal(self, precision)
134
+ end
135
+ end
136
+
137
+
138
+ class Complex < Numeric
139
+ # call-seq:
140
+ # cmp.to_d -> bigdecimal
141
+ # cmp.to_d(precision) -> bigdecimal
142
+ #
143
+ # Returns the value as a BigDecimal.
144
+ #
145
+ # The +precision+ parameter is required for a rational complex number.
146
+ # This parameter is used to determine the number of significant digits
147
+ # for the result.
148
+ #
149
+ # require 'bigdecimal'
150
+ # require 'bigdecimal/util'
151
+ #
152
+ # Complex(0.1234567, 0).to_d(4) # => 0.1235e0
153
+ # Complex(Rational(22, 7), 0).to_d(3) # => 0.314e1
154
+ #
155
+ # See also BigDecimal::new.
156
+ #
157
+ def to_d(*args)
158
+ BigDecimal(self) unless self.imag.zero? # to raise eerror
159
+
160
+ if args.length == 0
161
+ case self.real
162
+ when Rational
163
+ BigDecimal(self.real) # to raise error
164
+ end
165
+ end
166
+ self.real.to_d(*args)
167
+ end
168
+ end
169
+
170
+
171
+ class NilClass
172
+ # call-seq:
173
+ # nil.to_d -> bigdecimal
174
+ #
175
+ # Returns nil represented as a BigDecimal.
176
+ #
177
+ # require 'bigdecimal'
178
+ # require 'bigdecimal/util'
179
+ #
180
+ # nil.to_d # => 0.0
181
+ #
182
+ def to_d
183
+ BigDecimal(0)
184
+ end
185
+ end
data/lib/bigdecimal.rb ADDED
@@ -0,0 +1,5 @@
1
+ if RUBY_ENGINE == 'jruby'
2
+ JRuby::Util.load_ext("org.jruby.ext.bigdecimal.BigDecimalLibrary")
3
+ else
4
+ require 'bigdecimal.so'
5
+ end
data/sample/linear.rb ADDED
@@ -0,0 +1,74 @@
1
+ #!/usr/local/bin/ruby
2
+ # frozen_string_literal: false
3
+
4
+ #
5
+ # linear.rb
6
+ #
7
+ # Solves linear equation system(A*x = b) by LU decomposition method.
8
+ # where A is a coefficient matrix,x is an answer vector,b is a constant vector.
9
+ #
10
+ # USAGE:
11
+ # ruby linear.rb [input file solved]
12
+ #
13
+
14
+ # :stopdoc:
15
+ require "bigdecimal"
16
+ require "bigdecimal/ludcmp"
17
+
18
+ #
19
+ # NOTE:
20
+ # Change following BigDecimal.limit() if needed.
21
+ BigDecimal.limit(100)
22
+ #
23
+
24
+ include LUSolve
25
+ def rd_order(na)
26
+ printf("Number of equations ?") if(na <= 0)
27
+ n = ARGF.gets().to_i
28
+ end
29
+
30
+ na = ARGV.size
31
+ zero = BigDecimal("0.0")
32
+ one = BigDecimal("1.0")
33
+
34
+ while (n=rd_order(na))>0
35
+ a = []
36
+ as= []
37
+ b = []
38
+ if na <= 0
39
+ # Read data from console.
40
+ printf("\nEnter coefficient matrix element A[i,j]\n")
41
+ for i in 0...n do
42
+ for j in 0...n do
43
+ printf("A[%d,%d]? ",i,j); s = ARGF.gets
44
+ a << BigDecimal(s)
45
+ as << BigDecimal(s)
46
+ end
47
+ printf("Contatant vector element b[%d] ? ",i)
48
+ b << BigDecimal(ARGF.gets)
49
+ end
50
+ else
51
+ # Read data from specified file.
52
+ printf("Coefficient matrix and constant vector.\n")
53
+ for i in 0...n do
54
+ s = ARGF.gets
55
+ printf("%d) %s",i,s)
56
+ s = s.split
57
+ for j in 0...n do
58
+ a << BigDecimal(s[j])
59
+ as << BigDecimal(s[j])
60
+ end
61
+ b << BigDecimal(s[n])
62
+ end
63
+ end
64
+ x = lusolve(a,b,ludecomp(a,n,zero,one),zero)
65
+ printf("Answer(x[i] & (A*x-b)[i]) follows\n")
66
+ for i in 0...n do
67
+ printf("x[%d]=%s ",i,x[i].to_s)
68
+ s = zero
69
+ for j in 0...n do
70
+ s = s + as[i*n+j]*x[j]
71
+ end
72
+ printf(" & %s\n",(s-b[i]).to_s)
73
+ end
74
+ end
data/sample/nlsolve.rb ADDED
@@ -0,0 +1,40 @@
1
+ #!/usr/local/bin/ruby
2
+ # frozen_string_literal: false
3
+
4
+ #
5
+ # nlsolve.rb
6
+ # An example for solving nonlinear algebraic equation system.
7
+ #
8
+
9
+ require "bigdecimal"
10
+ require "bigdecimal/newton"
11
+ include Newton
12
+
13
+ class Function # :nodoc: all
14
+ def initialize()
15
+ @zero = BigDecimal("0.0")
16
+ @one = BigDecimal("1.0")
17
+ @two = BigDecimal("2.0")
18
+ @ten = BigDecimal("10.0")
19
+ @eps = BigDecimal("1.0e-16")
20
+ end
21
+ def zero;@zero;end
22
+ def one ;@one ;end
23
+ def two ;@two ;end
24
+ def ten ;@ten ;end
25
+ def eps ;@eps ;end
26
+ def values(x) # <= defines functions solved
27
+ f = []
28
+ f1 = x[0]*x[0] + x[1]*x[1] - @two # f1 = x**2 + y**2 - 2 => 0
29
+ f2 = x[0] - x[1] # f2 = x - y => 0
30
+ f <<= f1
31
+ f <<= f2
32
+ f
33
+ end
34
+ end
35
+
36
+ f = BigDecimal.limit(100)
37
+ f = Function.new
38
+ x = [f.zero,f.zero] # Initial values
39
+ n = nlsolve(f,x)
40
+ p x
data/sample/pi.rb ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/local/bin/ruby
2
+ # frozen_string_literal: false
3
+
4
+ #
5
+ # pi.rb
6
+ #
7
+ # Calculates 3.1415.... (the number of times that a circle's diameter
8
+ # will fit around the circle) using J. Machin's formula.
9
+ #
10
+
11
+ require "bigdecimal"
12
+ require "bigdecimal/math.rb"
13
+
14
+ include BigMath
15
+
16
+ if ARGV.size == 1
17
+ print "PI("+ARGV[0]+"):\n"
18
+ p PI(ARGV[0].to_i)
19
+ else
20
+ print "TRY: ruby pi.rb 1000 \n"
21
+ end
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bigdecimal
3
+ version: !ruby/object:Gem::Version
4
+ version: 3.1.4
5
+ platform: java
6
+ authors:
7
+ - Kenta Murata
8
+ - Zachary Scott
9
+ - Shigeo Kobayashi
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2023-09-05 00:00:00.000000000 Z
14
+ dependencies: []
15
+ description: This library provides arbitrary-precision decimal floating-point number
16
+ class.
17
+ email:
18
+ - mrkn@mrkn.jp
19
+ executables: []
20
+ extensions: []
21
+ extra_rdoc_files: []
22
+ files:
23
+ - bigdecimal.gemspec
24
+ - lib/bigdecimal.rb
25
+ - lib/bigdecimal/jacobian.rb
26
+ - lib/bigdecimal/ludcmp.rb
27
+ - lib/bigdecimal/math.rb
28
+ - lib/bigdecimal/newton.rb
29
+ - lib/bigdecimal/util.rb
30
+ - sample/linear.rb
31
+ - sample/nlsolve.rb
32
+ - sample/pi.rb
33
+ homepage: https://github.com/ruby/bigdecimal
34
+ licenses:
35
+ - Ruby
36
+ - BSD-2-Clause
37
+ metadata: {}
38
+ post_install_message:
39
+ rdoc_options: []
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 2.5.0
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ requirements: []
53
+ rubygems_version: 3.3.26
54
+ signing_key:
55
+ specification_version: 4
56
+ summary: Arbitrary-precision decimal floating-point number library.
57
+ test_files: []