bigdecimal-pure 0.1.0 → 0.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dc0062663b0a3bfb0ae8756397f9e02443c49dacb965a6a3da25e01d39c7554a
4
- data.tar.gz: 703b2fb877149972cf23ad3f5b0791510d4f5ed6932f3c8f5134d8c0053a37cd
3
+ metadata.gz: cf29bb03b15bb0bb1cbe340b2bc5a861f691af86d725f0d05122874ed2daeb64
4
+ data.tar.gz: 604104049ea023a06615056a809cd806ac446e7214d2ac8164002b4a232068ab
5
5
  SHA512:
6
- metadata.gz: 2e60b3c1dc4e26635a84add8eabbdfecb67007be7764318fbbcaaa38c3b9df14129c16e9686a090bbf5848c4b2501e3f629c03c1cdb72c96ab46e5b26bb8b9eb
7
- data.tar.gz: 9e23c4e38485648472c94c441199de7cc6a306b014d5b2653fa899a257b6c2a258716e512704e1dcc4b38fc833d49db3c2d82e8c5ebacf5e192f5f621c62b7aa
6
+ metadata.gz: b15e47a6978178e1199b4d51403b5fb5dfe3e9728d5ec7e165c358a91bd956b31e391a48708e94c2225079790797d5840e2e32e92969c35c78900ec5c34d4180
7
+ data.tar.gz: ea5fe695be57c79f4d3e45c5a609ffc8fec9464f025059c15dcedf8ed625dbc3ced159b5c0a7717161fa21295f741f191d4b987422571b8326e737cc45e15696
data/CHANGELOG.md CHANGED
@@ -1,8 +1,36 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.0] - 2026-09-30
4
+
5
+ The pure class now does what bigdecimal 4.x does, where 0.1.0 did not:
6
+
7
+ - NaN, `Infinity`, `-Infinity` and `-0`, with `BigDecimal::NAN` and
8
+ `BigDecimal::INFINITY`. `1 / 0` is `Infinity` and `0 / 0` is `NaN`, as in
9
+ the C version; 0.1.0 raised `ZeroDivisionError`.
10
+ - `BigDecimal.mode` for the exception modes and the rounding mode, and
11
+ `BigDecimal.limit`, per thread, with the `save_*` blocks.
12
+ - The precision of each result as in C: `/` keeps the larger operand's
13
+ precision plus 16 digits, at least 32 (0.1.0 used 20); Rational operands;
14
+ `add/sub/mult/div` with a precision; `sqrt(0)`; `power`.
15
+ - `BigMath` to any precision; 0.1.0 went through Float and was good to about
16
+ 15 digits. Also the functions bigdecimal 4.x added: `cbrt`, `hypot`, `tan`,
17
+ `asin`, `acos`, `atan2`, `sinh`, `cosh`, `tanh`, `asinh`, `acosh`, `atanh`,
18
+ `log2`, `log10`, `log1p`, `expm1`, `erf`, `erfc`, `gamma`, `lgamma`,
19
+ `frexp`, `ldexp`.
20
+ - `BigDecimal(float, digits)`, division and `ROUND_UP` round exactly as the C
21
+ version does, down to its 9-digit words.
22
+ - `BigDecimal.interpret_loosely`, every `to_s` format, `precision_scale`,
23
+ `n_significant_digits`, `split`, `_decimal_shift`.
24
+ - As in 4.x, `sqrt` needs its precision and `precs` is gone.
25
+
26
+ `test/compare_test.rb` runs about 8,500 expressions with the native and the
27
+ pure class and compares every result; `test/wasm_test.rb` runs them in
28
+ ruby.wasm.
29
+
3
30
  ## [0.1.0] - 2026-09-30
4
31
 
5
32
  - First release: BigDecimal in pure Ruby on Rational, taken from the ruby.wasm
6
33
  sandbox of Ren. `require 'bigdecimal'` prefers the native gem when installed.
7
34
 
35
+ [0.2.0]: https://github.com/Largo/bigdecimal-pure/releases/tag/v0.2.0
8
36
  [0.1.0]: https://github.com/Largo/bigdecimal-pure/releases/tag/v0.1.0
data/README.md CHANGED
@@ -11,8 +11,10 @@ gem 'bigdecimal-pure'
11
11
  ```ruby
12
12
  require 'bigdecimal' # native if available, pure Ruby otherwise
13
13
  require 'bigdecimal/util' # to_d, either way
14
+ require 'bigdecimal/math' # BigMath, either way
14
15
 
15
16
  BigDecimal('0.1') + BigDecimal('0.2') # => 0.3e0
17
+ BigMath.PI(50) # => 0.31415926535897932384626433832795028841971693993751e1
16
18
  BigDecimalPure.pure? # which one you got
17
19
  ```
18
20
 
@@ -29,20 +31,61 @@ load path that is not this gem's; on old Rubies it falls back to
29
31
 
30
32
  ## What the pure class does
31
33
 
32
- Built on `Rational`, so it is exact where BigDecimal is exact:
33
-
34
- - decimal strings (`"0.1" + "0.2"` is `0.3`), `+ - *`, rounding;
35
- - division and `sqrt` to 20 significant digits by default, like the original;
36
- - `round/floor/ceil/truncate` with digits and all `ROUND_*` modes;
37
- - `to_s` as `0.123e1`, `to_s('F')` as `1.23`; comparisons with Integer, Float
38
- and Rational; `to_d` from `bigdecimal/util`; `Marshal`.
39
-
40
- Not supported: NaN and Infinity (they raise), `BigDecimal.limit` and `.mode`,
41
- precision bookkeeping. `BigMath` goes through Float, so it is good to about 15
42
- digits whatever precision is asked for.
43
-
44
- Unlike [hanami-wasm's shim](https://github.com/katafrakt/hanami-wasm)
45
- (`BigDecimal(v) = v.to_i`), the value is kept: `BigDecimal("0.1")` is not 0.
34
+ What bigdecimal 4.x does, with the same results:
35
+
36
+ - decimal strings exactly (`"0.1" + "0.2"` is `0.3`), with the same grammar
37
+ as the C version, `BigDecimal.interpret_loosely` and `String#to_d`;
38
+ - NaN, `Infinity`, `-Infinity` and `-0`: `1 / 0` is `Infinity`, `0 / 0` is
39
+ `NaN`, and `BigDecimal.mode` turns each of them into an exception;
40
+ - `BigDecimal.mode(BigDecimal::ROUND_MODE, ...)` and `BigDecimal.limit`, per
41
+ thread, with `save_exception_mode`, `save_rounding_mode` and `save_limit`;
42
+ - the precision of each result: `+ - *` are exact unless a limit or a
43
+ precision argument says otherwise, `/` keeps the larger operand's precision
44
+ plus 16 digits (at least 32), a Rational operand is converted to as many
45
+ digits as the C version uses, `add/sub/mult/div(x, digits)` round to that;
46
+ - `round/floor/ceil/truncate` with digits, every `ROUND_*` mode and `half:`;
47
+ `%`, `divmod`, `remainder`; `**` and `power`, exact for Integer powers;
48
+ `sqrt(digits)`, exact when the root is;
49
+ - `to_s` in every format (`'F'`, `'E'`, digit groups, `'+'`, `' '`),
50
+ `precision`, `scale`, `n_significant_digits`, `exponent`, `split`,
51
+ `_dump`/`_load` for `Marshal`, comparisons and coercion with Integer, Float,
52
+ Rational and Complex;
53
+ - `BigDecimal(float, digits)` digit for digit as the C version, which rounds
54
+ with the dtoa of Ruby and inherits its one-half shortcut;
55
+ - `BigMath` to any precision: `exp`, `log`, `log2`, `log10`, `log1p`, `expm1`,
56
+ `sqrt`, `cbrt`, `hypot`, `sin`, `cos`, `tan`, `asin`, `acos`, `atan`, `atan2`,
57
+ `sinh`, `cosh`, `tanh`, `asinh`, `acosh`, `atanh`, `erf`, `erfc`, `gamma`,
58
+ `lgamma`, `frexp`, `ldexp`, `PI` and `E`.
59
+
60
+ The C version keeps its digits in 9-digit words, and a few results show it:
61
+ the precision of a Rational operand, the prefix of `_dump`, `ROUND_UP` to a
62
+ position far left of the number, and division, which rounds from the words
63
+ it has computed. The pure class counts those words too.
64
+
65
+ ### Where the two can differ
66
+
67
+ - `BigMath` computes each result with 24 more digits and rounds once; the C
68
+ version rounds after every step and carries 16. When the exact value lies
69
+ closer than about 10**-(prec + 16) to a number of `prec` digits — in a
70
+ rounding mode other than the half modes, or for an argument so small that
71
+ the result is nearly the argument or nearly 1 — the last digit can differ
72
+ by one. Where that happened in the tests, the pure result was the correct
73
+ one: `BigMath.cos(0, 10)` in `ROUND_DOWN` is `1`, the C version says
74
+ `0.9999999999`.
75
+ - `hash` values differ, and the C version's debugging methods (`vpdivd`,
76
+ `vpmult`, ...) and its internal `BigDecimal::Internal` are not there.
77
+ - It is Ruby: basic operations take a few microseconds instead of a fraction
78
+ of one. BigMath works on Integers and keeps up with the C version's, which
79
+ is Ruby too: faster at 50 digits, about even at 500 (gamma a little
80
+ slower).
81
+
82
+ ## Thanks
83
+
84
+ This gem only stands in where the real one cannot run. The real one is
85
+ [ruby/bigdecimal](https://github.com/ruby/bigdecimal), and its behaviour is
86
+ what this gem copies. Thank you to its authors and maintainers: Shigeo
87
+ Kobayashi, who wrote it, Kenta Murata, Zachary Scott, tompng, and everyone
88
+ who has contributed to it.
46
89
 
47
90
  ## Tests
48
91
 
@@ -50,6 +93,13 @@ Unlike [hanami-wasm's shim](https://github.com/katafrakt/hanami-wasm)
50
93
  bundle exec rake
51
94
  ```
52
95
 
96
+ runs the pure class against known values, checks that the native one loads
97
+ when it is there, and runs about 8,500 expressions with both and compares
98
+ every result, error class and message (`test/compare_test.rb`; more with
99
+ `CASES_SEED=7 CASES_SCALE=5`). `bundle exec rake wasm` runs the same
100
+ expressions in ruby.wasm under node, with `RUBY_WASM_DIST` pointing to the
101
+ `dist` directory of the npm package `@ruby/4.0-wasm-wasi`.
102
+
53
103
  ## License
54
104
 
55
105
  MIT
@@ -1,327 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # BigDecimal in pure Ruby, on top of Rational. lib/bigdecimal.rb loads this only
4
- # when no native bigdecimal can be found (ruby.wasm, sandboxes without a
5
- # compiler). Require it directly to get the pure version regardless.
3
+ # BigDecimal in pure Ruby. lib/bigdecimal.rb loads this only when no native
4
+ # bigdecimal can be found (ruby.wasm, sandboxes without a compiler). Require
5
+ # it directly to get the pure version regardless.
6
6
  #
7
- # Like the C version: decimal strings exactly ("0.1" + "0.2" is 0.3), + - *
8
- # exactly, division and sqrt to 20 significant digits by default,
9
- # round/floor/ceil/truncate with digits and the ROUND_* modes, to_s ("0.3e0",
10
- # or "0.3" with to_s('F')), comparisons with Integer, Float and Rational, to_d.
11
- # Not: NaN and Infinity (they raise), BigDecimal.limit and .mode, precision
12
- # bookkeeping. BigMath goes through Float, so it is good to about 15 digits.
7
+ # It behaves like bigdecimal 4.x: NaN, the infinities and -0, BigDecimal.mode
8
+ # and BigDecimal.limit, the precision rules of each operation, and BigMath to
9
+ # any precision. bigdecimal/util and bigdecimal/math come with it.
13
10
 
14
11
  require_relative '../bigdecimal_pure/version'
15
12
 
16
13
  return if defined?(BigDecimal)
17
14
 
18
- # rubocop:disable Lint/BigDecimalNew, Naming/PredicateMethod, Style/ReturnNilInPredicateMethodDefinition
19
- # -- this is BigDecimal: .new is its own constructor, and infinite?/nonzero? answer
20
- # nil as the C version does.
21
- class BigDecimal < Numeric
22
- ROUND_MODE = 256
23
- ROUND_UP = 1
24
- ROUND_DOWN = 2
25
- ROUND_HALF_UP = 3
26
- ROUND_HALF_DOWN = 4
27
- ROUND_CEILING = 5
28
- ROUND_FLOOR = 6
29
- ROUND_HALF_EVEN = 7
30
- SIGN_POSITIVE_ZERO = 1
31
- SIGN_NEGATIVE_ZERO = -1
32
- SIGN_POSITIVE_FINITE = 2
33
- SIGN_NEGATIVE_FINITE = -2
34
- DIV_DIGITS = 20
35
- VERSION = BigDecimalPure::VERSION
36
- PURE = true
37
-
38
- DECIMAL = /\A\s*([+-]?)(\d[\d_]*)?(?:\.(\d[\d_]*)?)?(?:[eEdD]([+-]?\d+))?\s*\z/
39
-
40
- attr_reader :rational
41
- protected :rational
42
-
43
- def self.parse(text)
44
- match = DECIMAL.match(text)
45
- if match.nil? || (match[2].nil? && match[3].nil?)
46
- raise ArgumentError, "invalid value for BigDecimal(): #{text.inspect}"
47
- end
48
-
49
- whole = match[2].to_s.delete('_')
50
- fraction = match[3].to_s.delete('_')
51
- digits = Integer("#{whole}#{fraction}".sub(/\A0+(?=\d)/, '').then { |s| s.empty? ? '0' : s }, 10)
52
- value = Rational(digits, 10**fraction.length) * (Rational(10)**match[4].to_i)
53
- match[1] == '-' ? -value : value
54
- end
55
-
56
- def self.from(value, digits = 0)
57
- case value
58
- when BigDecimal then value
59
- when Integer then new(Rational(value))
60
- when Rational then new(digits.positive? ? round_significant(value, digits) : value)
61
- when Float
62
- raise FloatDomainError, value.to_s unless value.finite?
63
-
64
- new(digits.positive? ? round_significant(value.to_r, digits) : parse(value.to_s))
65
- when String then new(parse(value))
66
- else
67
- raise TypeError, "can't convert #{value.class} into BigDecimal" unless value.respond_to?(:to_r)
68
-
69
- new(value.to_r)
70
- end
71
- end
72
-
73
- # Rounds to `digits` significant digits, half up.
74
- def self.round_significant(value, digits)
75
- return Rational(0) if value.zero?
76
-
77
- exponent = Math.log10(value.abs.to_f).floor rescue 0 # rubocop:disable Style/RescueModifier
78
- scale = digits - exponent - 1
79
- Rational((value * (Rational(10)**scale)).round, 1) / (Rational(10)**scale)
80
- end
81
-
82
- def self.double_fig = 16
83
- def self.limit(*) = 0
84
- def self.mode(*) = 0
85
- def self.save_rounding_mode = yield
86
- def self.save_exception_mode = yield
87
- def self.save_limit = yield
88
-
89
- def initialize(rational)
90
- super()
91
- @rational = rational
92
- freeze
93
- end
94
-
95
- def to_r = @rational
96
- def to_i = @rational.truncate
97
- alias to_int to_i
98
- def to_f = @rational.to_f
99
- def to_d = self
100
- def zero? = @rational.zero?
101
- def nonzero? = zero? ? nil : self
102
- def negative? = @rational.negative?
103
- def positive? = @rational.positive?
104
- def finite? = true
105
- def infinite? = nil
106
- def nan? = false
107
- def integer? = false
108
- def real? = true
109
- def hash = @rational.hash
110
- def precs = [digits_of.length, digits_of.length + DIV_DIGITS]
111
- def precision = digits_of.length
112
- def exponent = zero? ? 0 : Math.log10(@rational.abs.to_f).floor + 1
113
-
114
- def sign
115
- if zero? then SIGN_POSITIVE_ZERO
116
- else negative? ? SIGN_NEGATIVE_FINITE : SIGN_POSITIVE_FINITE
117
- end
118
- end
119
-
120
- def coerce(other) = [BigDecimal.from(other), self]
121
- def -@ = BigDecimal.new(-@rational)
122
- def +@ = self
123
- def abs = BigDecimal.new(@rational.abs)
124
-
125
- def +(other) = BigDecimal.new(@rational + value_of(other))
126
- def -(other) = BigDecimal.new(@rational - value_of(other))
127
- def *(other) = BigDecimal.new(@rational * value_of(other))
128
-
129
- def /(other)
130
- divisor = value_of(other)
131
- raise ZeroDivisionError, 'divided by 0' if divisor.zero?
132
-
133
- exact = @rational / divisor
134
- terminating?(exact) ? BigDecimal.new(exact) : BigDecimal.new(BigDecimal.round_significant(exact, DIV_DIGITS))
135
- end
136
- alias quo /
137
-
138
- def add(other, digits) = limit(self + other, digits)
139
- def sub(other, digits) = limit(self - other, digits)
140
- def mult(other, digits) = limit(self * other, digits)
141
-
142
- def div(other, digits = nil)
143
- return (self / other).floor if digits.nil?
144
-
145
- divisor = value_of(other)
146
- raise ZeroDivisionError, 'divided by 0' if divisor.zero?
147
-
148
- digits.zero? ? self / other : BigDecimal.new(BigDecimal.round_significant(@rational / divisor, digits))
149
- end
150
-
151
- def %(other) = BigDecimal.new(@rational % value_of(other))
152
- alias modulo %
153
- def remainder(other) = BigDecimal.new(@rational.remainder(value_of(other)))
154
- def divmod(other) = [div(other), self % other]
155
-
156
- def **(other)
157
- return BigDecimal.new(@rational**other) if other.is_a?(Integer)
158
-
159
- BigDecimal.from(to_f**other.to_f, DIV_DIGITS)
160
- end
161
- alias power **
162
-
163
- def sqrt(digits = DIV_DIGITS)
164
- raise FloatDomainError, 'sqrt of negative value' if negative?
165
-
166
- BigDecimal.from(Math.sqrt(to_f), [digits, 15].min)
167
- end
168
-
169
- def <=>(other)
170
- other.is_a?(Numeric) ? @rational <=> value_of(other) : nil
171
- end
172
-
173
- def ==(other) = other.is_a?(Numeric) && @rational == value_of(other)
174
- alias eql? ==
175
- alias === ==
176
- include Comparable
177
-
178
- # Without digits an Integer, as in the C version; with digits a BigDecimal.
179
- def round(*args, half: nil)
180
- digits = args[0].is_a?(Integer) ? args[0] : 0
181
- half = { up: ROUND_HALF_UP, down: ROUND_HALF_DOWN, even: ROUND_HALF_EVEN }[half]
182
- mode = args.find { |arg| arg.is_a?(Symbol) } || (args[1].is_a?(Integer) ? args[1] : nil) || half || ROUND_HALF_UP
183
- rounded = round_to(digits, mode)
184
- args.empty? ? rounded.to_i : rounded
185
- end
186
-
187
- def floor(digits = 0) = digits.zero? ? @rational.floor : round_to(digits, ROUND_FLOOR)
188
- def ceil(digits = 0) = digits.zero? ? @rational.ceil : round_to(digits, ROUND_CEILING)
189
- def truncate(digits = 0) = digits.zero? ? @rational.truncate : round_to(digits, ROUND_DOWN)
190
- alias fix truncate
191
-
192
- def frac = BigDecimal.new(@rational - @rational.truncate)
193
-
194
- # "0.123e1" like the C version; to_s('F') for plain notation.
195
- def to_s(format = nil)
196
- return plain if format.to_s.upcase.include?('F')
197
- return '0.0' if zero?
198
-
199
- digits = digits_of
200
- "#{'-' if negative?}0.#{digits}e#{exponent_of}"
201
- end
202
-
203
- def inspect = to_s
204
- def to_digits = plain
205
-
206
- def _dump(_level = 0) = to_s
207
- def self._load(text) = from(text)
208
-
209
- private
210
-
211
- def value_of(other)
212
- case other
213
- when BigDecimal then other.rational
214
- when Integer, Rational then other.to_r
215
- when Float
216
- raise FloatDomainError, other.to_s unless other.finite?
217
-
218
- BigDecimal.parse(other.to_s)
219
- else
220
- raise TypeError, "#{other.class} can't be coerced into BigDecimal" unless other.respond_to?(:to_r)
221
-
222
- other.to_r
223
- end
224
- end
225
-
226
- def limit(value, digits)
227
- digits.to_i.positive? ? BigDecimal.new(BigDecimal.round_significant(value.to_r, digits.to_i)) : value
228
- end
229
-
230
- def terminating?(value)
231
- denominator = value.denominator
232
- denominator /= 2 while (denominator % 2).zero?
233
- denominator /= 5 while (denominator % 5).zero?
234
- denominator == 1
235
- end
236
-
237
- # All significant digits, without leading or trailing zeros.
238
- def digits_of
239
- text = plain.delete('-').delete('.').sub(/\A0+/, '').sub(/0+\z/, '')
240
- text.empty? ? '0' : text
241
- end
242
-
243
- def exponent_of
244
- whole, fraction = plain.delete('-').split('.')
245
- return whole.length if whole != '0'
246
-
247
- -(fraction.length - fraction.sub(/\A0+/, '').length)
248
- end
249
-
250
- # Plain decimal notation. Every value here terminates: strings, Integers and
251
- # Floats parse to finite decimals, and division rounds when it would not.
252
- def plain
253
- value = @rational.abs
254
- scale = 0
255
- scale += 1 until (value * (10**scale)).denominator == 1 || scale > 1000
256
- digits = (value * (10**scale)).round.to_s.rjust(scale + 1, '0')
257
- whole = digits[0...(digits.length - scale)]
258
- fraction = scale.zero? ? '0' : digits[(digits.length - scale)..].sub(/0+\z/, '')
259
- fraction = '0' if fraction.empty?
260
- "#{'-' if negative?}#{whole}.#{fraction}"
261
- end
262
-
263
- def round_to(digits, mode)
264
- scale = Rational(10)**digits
265
- scaled = @rational * scale
266
- whole = case mode
267
- when ROUND_UP, :up then scaled.negative? ? scaled.floor : scaled.ceil
268
- when ROUND_DOWN, :down, :truncate then scaled.truncate
269
- when ROUND_CEILING, :ceiling, :ceil then scaled.ceil
270
- when ROUND_FLOOR, :floor then scaled.floor
271
- when ROUND_HALF_DOWN, :half_down then half(scaled, :down)
272
- when ROUND_HALF_EVEN, :half_even, :banker then half(scaled, :even)
273
- else scaled.round(half: :up)
274
- end
275
- BigDecimal.new(Rational(whole) / scale)
276
- end
277
-
278
- def half(scaled, way) = scaled.round(half: way)
279
- end
280
- # rubocop:enable Lint/BigDecimalNew, Naming/PredicateMethod, Style/ReturnNilInPredicateMethodDefinition
281
-
282
- module Kernel
283
- def BigDecimal(value, digits = 0, exception: true) # rubocop:disable Naming/MethodName
284
- BigDecimal.from(value, digits)
285
- rescue ArgumentError, TypeError
286
- raise if exception
287
-
288
- nil
289
- end
290
- module_function :BigDecimal
291
- public :BigDecimal
292
- end
293
-
294
- # bigdecimal/util: to_d on the numbers and strings.
295
- class Integer
296
- def to_d = BigDecimal(self)
297
- end
298
-
299
- class Float
300
- def to_d(digits = 0) = BigDecimal(self, digits)
301
- end
302
-
303
- class Rational
304
- def to_d(digits) = BigDecimal(self, digits)
305
- end
306
-
307
- class String
308
- def to_d = BigDecimal(self, exception: false) || BigDecimal(0)
309
- end
310
-
311
- class NilClass
312
- def to_d = BigDecimal(0)
313
- end
314
-
315
- # bigdecimal/math, through Float: about 15 good digits whatever is asked for.
316
- module BigMath
317
- module_function
318
-
319
- def exp(value, digits) = BigDecimal(Math.exp(value.to_f), [digits, 15].min)
320
- def log(value, digits) = BigDecimal(Math.log(value.to_f), [digits, 15].min)
321
- def sqrt(value, digits) = BigDecimal(value).sqrt(digits)
322
- def PI(digits) = BigDecimal(Math::PI, [digits, 15].min) # rubocop:disable Naming/MethodName
323
- def E(digits) = BigDecimal(Math::E, [digits, 15].min) # rubocop:disable Naming/MethodName
324
- def sin(value, digits) = BigDecimal(Math.sin(value.to_f), [digits, 15].min)
325
- def cos(value, digits) = BigDecimal(Math.cos(value.to_f), [digits, 15].min)
326
- def atan(value, digits) = BigDecimal(Math.atan(value.to_f), [digits, 15].min)
327
- end
15
+ require_relative '../bigdecimal_pure/decimal'
16
+ require_relative '../bigdecimal_pure/math'
17
+ require_relative '../bigdecimal_pure/util'