bigdecimal 3.3.1 → 4.0.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: 5446d4c544dfb6172f0b215366aed68dd7a3df1cceef23c2fa7735d55489c93a
4
- data.tar.gz: 2f17c5cf3a70a9131446dacbdc6fda43e0ac4dce58f8041446e94b6ad9b5e22c
3
+ metadata.gz: 218ec856a55103fe791e5478b1d9a2e1256f1d9eebb20ad69f3ab9319a84dda6
4
+ data.tar.gz: 004e5a6c9481412f548c5244c18620247592c53a39e3b6e65aaa6c3ff9ed8cdc
5
5
  SHA512:
6
- metadata.gz: ecc33314be340556b87315c8b95b93c9f8657d01c76fd08265cd7cc4028cc8400c804533dc1db810c439761ee5e85aa7c75d7ebc959de40d726c50fd7798852b
7
- data.tar.gz: 4e7a4d1271238dbda723e4e89b868250f666744b98476edcb50a55d541aa19ad5e3f85610f572ce4061f42bc13cf34732bf1bf8a1a3f84bd4e060ed99ab221f7
6
+ metadata.gz: f9c25edb664fe67c7e4b6892629ef41a73183bee8a592b3f15885baac834bfa193b1dbf88622a85db42608f15fc9156046a934c030731159f14d97709b032d5c
7
+ data.tar.gz: ec44919000395e1b9dd463bdfcfe87b0c8c21999a40099b24b009d453dcfd7cefbfc8e0faf62b6a8c5fe49ab90bada5cee75d1be0bbb97d65a5a698fff5ef26a
@@ -31,7 +31,7 @@
31
31
  #include "bits.h"
32
32
  #include "static_assert.h"
33
33
 
34
- #define BIGDECIMAL_VERSION "3.3.1"
34
+ #define BIGDECIMAL_VERSION "4.0.0"
35
35
 
36
36
  /* #define ENABLE_NUMERIC_STRING */
37
37
 
@@ -400,37 +400,6 @@ BigDecimal_double_fig(VALUE self)
400
400
  return INT2FIX(BIGDECIMAL_DOUBLE_FIGURES);
401
401
  }
402
402
 
403
- /* call-seq:
404
- * precs -> array
405
- *
406
- * Returns an Array of two Integer values that represent platform-dependent
407
- * internal storage properties.
408
- *
409
- * This method is deprecated and will be removed in the future.
410
- * Instead, use BigDecimal#n_significant_digits for obtaining the number of
411
- * significant digits in scientific notation, and BigDecimal#precision for
412
- * obtaining the number of digits in decimal notation.
413
- *
414
- */
415
-
416
- static VALUE
417
- BigDecimal_prec(VALUE self)
418
- {
419
- BDVALUE v;
420
- VALUE obj;
421
-
422
- rb_category_warn(RB_WARN_CATEGORY_DEPRECATED,
423
- "BigDecimal#precs is deprecated and will be removed in the future; "
424
- "use BigDecimal#precision instead.");
425
-
426
- v = GetBDValueMust(self);
427
- obj = rb_assoc_new(SIZET2NUM(v.real->Prec*VpBaseFig()),
428
- SIZET2NUM(v.real->MaxPrec*VpBaseFig()));
429
-
430
- RB_GC_GUARD(v.bigdecimal);
431
- return obj;
432
- }
433
-
434
403
  static void
435
404
  VpCountPrecisionAndScale(Real *p, ssize_t *out_precision, ssize_t *out_scale)
436
405
  {
@@ -1867,7 +1836,7 @@ BigDecimal_divmod(VALUE self, VALUE r)
1867
1836
  NULLABLE_BDVALUE div, mod;
1868
1837
 
1869
1838
  if (BigDecimal_DoDivmod(self, r, &div, &mod, false)) {
1870
- return rb_assoc_new(CheckGetValue(bdvalue_nonnullable(div)), CheckGetValue(bdvalue_nonnullable(mod)));
1839
+ return rb_assoc_new(BigDecimal_to_i(CheckGetValue(bdvalue_nonnullable(div))), CheckGetValue(bdvalue_nonnullable(mod)));
1871
1840
  }
1872
1841
  return DoSomeOne(self,r,rb_intern("divmod"));
1873
1842
  }
@@ -2507,7 +2476,7 @@ BigDecimal_decimal_shift(VALUE self, VALUE v)
2507
2476
  prec = a.real->Prec + shiftDown;
2508
2477
  c = NewZeroWrap(1, prec * BASE_FIG);
2509
2478
  if (shift == 0) {
2510
- VpAsgn(c.real, a.real, 1);
2479
+ VpAsgn(c.real, a.real, 10);
2511
2480
  } else if (shiftDown) {
2512
2481
  DECDIG carry = 0;
2513
2482
  exponentShift++;
@@ -3593,7 +3562,6 @@ Init_bigdecimal(void)
3593
3562
  rb_define_const(rb_cBigDecimal, "NAN", BIGDECIMAL_LITERAL(NAN, NaN));
3594
3563
 
3595
3564
  /* instance methods */
3596
- rb_define_method(rb_cBigDecimal, "precs", BigDecimal_prec, 0);
3597
3565
  rb_define_method(rb_cBigDecimal, "precision", BigDecimal_precision, 0);
3598
3566
  rb_define_method(rb_cBigDecimal, "scale", BigDecimal_scale, 0);
3599
3567
  rb_define_method(rb_cBigDecimal, "precision_scale", BigDecimal_precision_scale, 0);
@@ -6166,7 +6134,7 @@ VpFrac(Real *y, Real *x)
6166
6134
  size_t my, ind_y, ind_x;
6167
6135
 
6168
6136
  if (!VpHasVal(x)) {
6169
- VpAsgn(y, x, 1);
6137
+ VpAsgn(y, x, 10);
6170
6138
  goto Exit;
6171
6139
  }
6172
6140
 
@@ -6175,7 +6143,7 @@ VpFrac(Real *y, Real *x)
6175
6143
  goto Exit;
6176
6144
  }
6177
6145
  else if (x->exponent <= 0) {
6178
- VpAsgn(y, x, 1);
6146
+ VpAsgn(y, x, 10);
6179
6147
  goto Exit;
6180
6148
  }
6181
6149
 
@@ -2,6 +2,8 @@
2
2
 
3
3
  require 'bigdecimal'
4
4
 
5
+ warn "'bigdecimal/jacobian' is deprecated and will be removed in a future release."
6
+
5
7
  # require 'bigdecimal/jacobian'
6
8
  #
7
9
  # Provides methods to compute the Jacobian matrix of a set of equations at a
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: false
2
2
  require 'bigdecimal'
3
3
 
4
+ warn "'bigdecimal/ludcmp' is deprecated and will be removed in a future release."
5
+
4
6
  #
5
7
  # Solves a*x = b for x, using LU decomposition.
6
8
  #
@@ -5,15 +5,36 @@ require 'bigdecimal'
5
5
  #--
6
6
  # Contents:
7
7
  # sqrt(x, prec)
8
+ # cbrt(x, prec)
9
+ # hypot(x, y, prec)
8
10
  # sin (x, prec)
9
11
  # cos (x, prec)
10
12
  # tan (x, prec)
13
+ # asin(x, prec)
14
+ # acos(x, prec)
11
15
  # atan(x, prec)
16
+ # atan2(y, x, prec)
17
+ # sinh (x, prec)
18
+ # cosh (x, prec)
19
+ # tanh (x, prec)
20
+ # asinh(x, prec)
21
+ # acosh(x, prec)
22
+ # atanh(x, prec)
23
+ # log2 (x, prec)
24
+ # log10(x, prec)
25
+ # log1p(x, prec)
26
+ # expm1(x, prec)
27
+ # erf (x, prec)
28
+ # erfc(x, prec)
29
+ # gamma(x, prec)
30
+ # lgamma(x, prec)
31
+ # frexp(x)
32
+ # ldexp(x, exponent)
12
33
  # PI (prec)
13
34
  # E (prec) == exp(1.0,prec)
14
35
  #
15
36
  # where:
16
- # x ... BigDecimal number to be computed.
37
+ # x, y ... BigDecimal number to be computed.
17
38
  # prec ... Number of digits to be obtained.
18
39
  #++
19
40
  #
@@ -73,6 +94,53 @@ module BigMath
73
94
  end
74
95
  end
75
96
 
97
+ # call-seq:
98
+ # cbrt(decimal, numeric) -> BigDecimal
99
+ #
100
+ # Computes the cube root of +decimal+ to the specified number of digits of
101
+ # precision, +numeric+.
102
+ #
103
+ # BigMath.cbrt(BigDecimal('2'), 32).to_s
104
+ # #=> "0.12599210498948731647672106072782e1"
105
+ #
106
+ def cbrt(x, prec)
107
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :cbrt)
108
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :cbrt)
109
+ return BigDecimal::Internal.nan_computation_result if x.nan?
110
+ return BigDecimal::Internal.infinity_computation_result * x.infinite? if x.infinite?
111
+ return BigDecimal(0) if x.zero?
112
+
113
+ x = -x if neg = x < 0
114
+ ex = x.exponent / 3
115
+ x = x._decimal_shift(-3 * ex)
116
+ y = BigDecimal(Math.cbrt(x.to_f), 0)
117
+ precs = [prec + BigDecimal.double_fig]
118
+ precs << 2 + precs.last / 2 while precs.last > BigDecimal.double_fig
119
+ precs.reverse_each do |p|
120
+ y = (2 * y + x.div(y, p).div(y, p)).div(3, p)
121
+ end
122
+ y._decimal_shift(ex).mult(neg ? -1 : 1, prec)
123
+ end
124
+
125
+ # call-seq:
126
+ # hypot(x, y, numeric) -> BigDecimal
127
+ #
128
+ # Returns sqrt(x**2 + y**2) to the specified number of digits of
129
+ # precision, +numeric+.
130
+ #
131
+ # BigMath.hypot(BigDecimal('1'), BigDecimal('2'), 32).to_s
132
+ # #=> "0.22360679774997896964091736687313e1"
133
+ #
134
+ def hypot(x, y, prec)
135
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :hypot)
136
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :hypot)
137
+ y = BigDecimal::Internal.coerce_to_bigdecimal(y, prec, :hypot)
138
+ return BigDecimal::Internal.nan_computation_result if x.nan? || y.nan?
139
+ return BigDecimal::Internal.infinity_computation_result if x.infinite? || y.infinite?
140
+ prec2 = prec + BigDecimal.double_fig
141
+ sqrt(x.mult(x, prec2) + y.mult(y, prec2), prec)
142
+ end
143
+
76
144
  # call-seq:
77
145
  # sin(decimal, numeric) -> BigDecimal
78
146
  #
@@ -148,6 +216,57 @@ module BigMath
148
216
  sin(x, prec + BigDecimal.double_fig).div(cos(x, prec + BigDecimal.double_fig), prec)
149
217
  end
150
218
 
219
+ # call-seq:
220
+ # asin(decimal, numeric) -> BigDecimal
221
+ #
222
+ # Computes the arcsine of +decimal+ to the specified number of digits of
223
+ # precision, +numeric+.
224
+ #
225
+ # If +decimal+ is NaN, returns NaN.
226
+ #
227
+ # BigMath.asin(BigDecimal('0.5'), 32).to_s
228
+ # #=> "0.52359877559829887307710723054658e0"
229
+ #
230
+ def asin(x, prec)
231
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :asin)
232
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :asin)
233
+ raise Math::DomainError, "Out of domain argument for asin" if x < -1 || x > 1
234
+ return BigDecimal::Internal.nan_computation_result if x.nan?
235
+
236
+ prec2 = prec + BigDecimal.double_fig
237
+ cos = (1 - x**2).sqrt(prec2)
238
+ if cos.zero?
239
+ PI(prec2).div(x > 0 ? 2 : -2, prec)
240
+ else
241
+ atan(x.div(cos, prec2), prec)
242
+ end
243
+ end
244
+
245
+ # call-seq:
246
+ # acos(decimal, numeric) -> BigDecimal
247
+ #
248
+ # Computes the arccosine of +decimal+ to the specified number of digits of
249
+ # precision, +numeric+.
250
+ #
251
+ # If +decimal+ is NaN, returns NaN.
252
+ #
253
+ # BigMath.acos(BigDecimal('0.5'), 32).to_s
254
+ # #=> "0.10471975511965977461542144610932e1"
255
+ #
256
+ def acos(x, prec)
257
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :acos)
258
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :acos)
259
+ raise Math::DomainError, "Out of domain argument for acos" if x < -1 || x > 1
260
+ return BigDecimal::Internal.nan_computation_result if x.nan?
261
+
262
+ prec2 = prec + BigDecimal.double_fig
263
+ return (PI(prec2) / 2).sub(asin(x, prec2), prec) if x < 0
264
+ return PI(prec2).div(2, prec) if x.zero?
265
+
266
+ sin = (1 - x**2).sqrt(prec2)
267
+ atan(sin.div(x, prec2), prec)
268
+ end
269
+
151
270
  # call-seq:
152
271
  # atan(decimal, numeric) -> BigDecimal
153
272
  #
@@ -167,7 +286,7 @@ module BigMath
167
286
  pi = PI(n)
168
287
  x = -x if neg = x < 0
169
288
  return pi.div(neg ? -2 : 2, prec) if x.infinite?
170
- return pi.div(neg ? -4 : 4, prec) if x.round(prec) == 1
289
+ return pi.div(neg ? -4 : 4, prec) if x.round(n) == 1
171
290
  x = BigDecimal("1").div(x, n) if inv = x > 1
172
291
  x = (-1 + sqrt(1 + x.mult(x, n), n)).div(x, n) if dbl = x > 0.5
173
292
  y = x
@@ -188,6 +307,587 @@ module BigMath
188
307
  y.mult(1, prec)
189
308
  end
190
309
 
310
+ # call-seq:
311
+ # atan2(decimal, decimal, numeric) -> BigDecimal
312
+ #
313
+ # Computes the arctangent of y and x to the specified number of digits of
314
+ # precision, +numeric+.
315
+ #
316
+ # BigMath.atan2(BigDecimal('-1'), BigDecimal('1'), 32).to_s
317
+ # #=> "-0.78539816339744830961566084581988e0"
318
+ #
319
+ def atan2(y, x, prec)
320
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :atan2)
321
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :atan2)
322
+ y = BigDecimal::Internal.coerce_to_bigdecimal(y, prec, :atan2)
323
+ return BigDecimal::Internal.nan_computation_result if x.nan? || y.nan?
324
+
325
+ if x.infinite? || y.infinite?
326
+ one = BigDecimal(1)
327
+ zero = BigDecimal(0)
328
+ x = x.infinite? ? (x > 0 ? one : -one) : zero
329
+ y = y.infinite? ? (y > 0 ? one : -one) : y.sign * zero
330
+ end
331
+
332
+ return x.sign >= 0 ? BigDecimal(0) : y.sign * PI(prec) if y.zero?
333
+
334
+ y = -y if neg = y < 0
335
+ xlarge = y.abs < x.abs
336
+ prec2 = prec + BigDecimal.double_fig
337
+ if x > 0
338
+ v = xlarge ? atan(y.div(x, prec2), prec) : PI(prec2) / 2 - atan(x.div(y, prec2), prec2)
339
+ else
340
+ v = xlarge ? PI(prec2) - atan(-y.div(x, prec2), prec2) : PI(prec2) / 2 + atan(x.div(-y, prec2), prec2)
341
+ end
342
+ v.mult(neg ? -1 : 1, prec)
343
+ end
344
+
345
+ # call-seq:
346
+ # sinh(decimal, numeric) -> BigDecimal
347
+ #
348
+ # Computes the hyperbolic sine of +decimal+ to the specified number of digits of
349
+ # precision, +numeric+.
350
+ #
351
+ # If +decimal+ is NaN, returns NaN.
352
+ #
353
+ # BigMath.sinh(BigDecimal('1'), 32).to_s
354
+ # #=> "0.11752011936438014568823818505956e1"
355
+ #
356
+ def sinh(x, prec)
357
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :sinh)
358
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :sinh)
359
+ return BigDecimal::Internal.nan_computation_result if x.nan?
360
+ return BigDecimal::Internal.infinity_computation_result * x.infinite? if x.infinite?
361
+
362
+ prec2 = prec + BigDecimal.double_fig
363
+ prec2 -= x.exponent if x.exponent < 0
364
+ e = exp(x, prec2)
365
+ (e - BigDecimal(1).div(e, prec2)).div(2, prec)
366
+ end
367
+
368
+ # call-seq:
369
+ # cosh(decimal, numeric) -> BigDecimal
370
+ #
371
+ # Computes the hyperbolic cosine of +decimal+ to the specified number of digits of
372
+ # precision, +numeric+.
373
+ #
374
+ # If +decimal+ is NaN, returns NaN.
375
+ #
376
+ # BigMath.cosh(BigDecimal('1'), 32).to_s
377
+ # #=> "0.15430806348152437784779056207571e1"
378
+ #
379
+ def cosh(x, prec)
380
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :cosh)
381
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :cosh)
382
+ return BigDecimal::Internal.nan_computation_result if x.nan?
383
+ return BigDecimal::Internal.infinity_computation_result if x.infinite?
384
+
385
+ prec2 = prec + BigDecimal.double_fig
386
+ e = exp(x, prec2)
387
+ (e + BigDecimal(1).div(e, prec2)).div(2, prec)
388
+ end
389
+
390
+ # call-seq:
391
+ # tanh(decimal, numeric) -> BigDecimal
392
+ #
393
+ # Computes the hyperbolic tangent of +decimal+ to the specified number of digits of
394
+ # precision, +numeric+.
395
+ #
396
+ # If +decimal+ is NaN, returns NaN.
397
+ #
398
+ # BigMath.tanh(BigDecimal('1'), 32).to_s
399
+ # #=> "0.76159415595576488811945828260479e0"
400
+ #
401
+ def tanh(x, prec)
402
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :tanh)
403
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :tanh)
404
+ return BigDecimal::Internal.nan_computation_result if x.nan?
405
+ return BigDecimal(x.infinite?) if x.infinite?
406
+
407
+ prec2 = prec + BigDecimal.double_fig + [-x.exponent, 0].max
408
+ e = exp(x, prec2)
409
+ einv = BigDecimal(1).div(e, prec2)
410
+ (e - einv).div(e + einv, prec)
411
+ end
412
+
413
+ # call-seq:
414
+ # asinh(decimal, numeric) -> BigDecimal
415
+ #
416
+ # Computes the inverse hyperbolic sine of +decimal+ to the specified number of digits of
417
+ # precision, +numeric+.
418
+ #
419
+ # If +decimal+ is NaN, returns NaN.
420
+ #
421
+ # BigMath.asinh(BigDecimal('1'), 32).to_s
422
+ # #=> "0.88137358701954302523260932497979e0"
423
+ #
424
+ def asinh(x, prec)
425
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :asinh)
426
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :asinh)
427
+ return BigDecimal::Internal.nan_computation_result if x.nan?
428
+ return BigDecimal::Internal.infinity_computation_result * x.infinite? if x.infinite?
429
+ return -asinh(-x, prec) if x < 0
430
+
431
+ sqrt_prec = prec + [-x.exponent, 0].max + BigDecimal.double_fig
432
+ log(x + sqrt(x**2 + 1, sqrt_prec), prec)
433
+ end
434
+
435
+ # call-seq:
436
+ # acosh(decimal, numeric) -> BigDecimal
437
+ #
438
+ # Computes the inverse hyperbolic cosine of +decimal+ to the specified number of digits of
439
+ # precision, +numeric+.
440
+ #
441
+ # If +decimal+ is NaN, returns NaN.
442
+ #
443
+ # BigMath.acosh(BigDecimal('2'), 32).to_s
444
+ # #=> "0.1316957896924816708625046347308e1"
445
+ #
446
+ def acosh(x, prec)
447
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :acosh)
448
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :acosh)
449
+ raise Math::DomainError, "Out of domain argument for acosh" if x < 1
450
+ return BigDecimal::Internal.infinity_computation_result if x.infinite?
451
+ return BigDecimal::Internal.nan_computation_result if x.nan?
452
+
453
+ log(x + sqrt(x**2 - 1, prec + BigDecimal.double_fig), prec)
454
+ end
455
+
456
+ # call-seq:
457
+ # atanh(decimal, numeric) -> BigDecimal
458
+ #
459
+ # Computes the inverse hyperbolic tangent of +decimal+ to the specified number of digits of
460
+ # precision, +numeric+.
461
+ #
462
+ # If +decimal+ is NaN, returns NaN.
463
+ #
464
+ # BigMath.atanh(BigDecimal('0.5'), 32).to_s
465
+ # #=> "0.54930614433405484569762261846126e0"
466
+ #
467
+ def atanh(x, prec)
468
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :atanh)
469
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :atanh)
470
+ raise Math::DomainError, "Out of domain argument for atanh" if x < -1 || x > 1
471
+ return BigDecimal::Internal.nan_computation_result if x.nan?
472
+ return BigDecimal::Internal.infinity_computation_result if x == 1
473
+ return -BigDecimal::Internal.infinity_computation_result if x == -1
474
+
475
+ prec2 = prec + BigDecimal.double_fig
476
+ (log(x + 1, prec2) - log(1 - x, prec2)).div(2, prec)
477
+ end
478
+
479
+ # call-seq:
480
+ # BigMath.log2(decimal, numeric) -> BigDecimal
481
+ #
482
+ # Computes the base 2 logarithm of +decimal+ to the specified number of
483
+ # digits of precision, +numeric+.
484
+ #
485
+ # If +decimal+ is zero or negative, raises Math::DomainError.
486
+ #
487
+ # If +decimal+ is positive infinity, returns Infinity.
488
+ #
489
+ # If +decimal+ is NaN, returns NaN.
490
+ #
491
+ # BigMath.log2(BigDecimal('3'), 32).to_s
492
+ # #=> "0.15849625007211561814537389439478e1"
493
+ #
494
+ def log2(x, prec)
495
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :log2)
496
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :log2)
497
+ return BigDecimal::Internal.nan_computation_result if x.nan?
498
+ return BigDecimal::Internal.infinity_computation_result if x.infinite? == 1
499
+
500
+ prec2 = prec + BigDecimal.double_fig * 3 / 2
501
+ v = log(x, prec2).div(log(BigDecimal(2), prec2), prec2)
502
+ # Perform half-up rounding to calculate log2(2**n)==n correctly in every rounding mode
503
+ v = v.round(prec + BigDecimal.double_fig - (v.exponent < 0 ? v.exponent : 0), BigDecimal::ROUND_HALF_UP)
504
+ v.mult(1, prec)
505
+ end
506
+
507
+ # call-seq:
508
+ # BigMath.log10(decimal, numeric) -> BigDecimal
509
+ #
510
+ # Computes the base 10 logarithm of +decimal+ to the specified number of
511
+ # digits of precision, +numeric+.
512
+ #
513
+ # If +decimal+ is zero or negative, raises Math::DomainError.
514
+ #
515
+ # If +decimal+ is positive infinity, returns Infinity.
516
+ #
517
+ # If +decimal+ is NaN, returns NaN.
518
+ #
519
+ # BigMath.log10(BigDecimal('3'), 32).to_s
520
+ # #=> "0.47712125471966243729502790325512e0"
521
+ #
522
+ def log10(x, prec)
523
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :log10)
524
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :log10)
525
+ return BigDecimal::Internal.nan_computation_result if x.nan?
526
+ return BigDecimal::Internal.infinity_computation_result if x.infinite? == 1
527
+
528
+ prec2 = prec + BigDecimal.double_fig * 3 / 2
529
+ v = log(x, prec2).div(log(BigDecimal(10), prec2), prec2)
530
+ # Perform half-up rounding to calculate log10(10**n)==n correctly in every rounding mode
531
+ v = v.round(prec + BigDecimal.double_fig - (v.exponent < 0 ? v.exponent : 0), BigDecimal::ROUND_HALF_UP)
532
+ v.mult(1, prec)
533
+ end
534
+
535
+ # call-seq:
536
+ # BigMath.log1p(decimal, numeric) -> BigDecimal
537
+ #
538
+ # Computes log(1 + decimal) to the specified number of digits of precision, +numeric+.
539
+ #
540
+ # BigMath.log1p(BigDecimal('0.1'), 32).to_s
541
+ # #=> "0.95310179804324860043952123280765e-1"
542
+ #
543
+ def log1p(x, prec)
544
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :log1p)
545
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :log1p)
546
+ raise Math::DomainError, 'Out of domain argument for log1p' if x < -1
547
+
548
+ return log(x + 1, prec)
549
+ end
550
+
551
+ # call-seq:
552
+ # BigMath.expm1(decimal, numeric) -> BigDecimal
553
+ #
554
+ # Computes exp(decimal) - 1 to the specified number of digits of precision, +numeric+.
555
+ #
556
+ # BigMath.expm1(BigDecimal('0.1'), 32).to_s
557
+ # #=> "0.10517091807564762481170782649025e0"
558
+ #
559
+ def expm1(x, prec)
560
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :expm1)
561
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :expm1)
562
+ return BigDecimal(-1) if x.infinite? == -1
563
+
564
+ exp_prec = prec
565
+ if x < -1
566
+ # log10(exp(x)) = x * log10(e)
567
+ lg_e = 0.4342944819032518
568
+ exp_prec = prec + (lg_e * x).ceil + BigDecimal.double_fig
569
+ elsif x < 1
570
+ exp_prec = prec - x.exponent + BigDecimal.double_fig
571
+ else
572
+ exp_prec = prec
573
+ end
574
+
575
+ return BigDecimal(-1) if exp_prec <= 0
576
+
577
+ exp = exp(x, exp_prec)
578
+
579
+ if exp.exponent > prec + BigDecimal.double_fig
580
+ # Workaroudn for https://github.com/ruby/bigdecimal/issues/464
581
+ exp
582
+ else
583
+ exp.sub(1, prec)
584
+ end
585
+ end
586
+
587
+ # erf(decimal, numeric) -> BigDecimal
588
+ #
589
+ # Computes the error function of +decimal+ to the specified number of digits of
590
+ # precision, +numeric+.
591
+ #
592
+ # If +decimal+ is NaN, returns NaN.
593
+ #
594
+ # BigMath.erf(BigDecimal('1'), 32).to_s
595
+ # #=> "0.84270079294971486934122063508261e0"
596
+ #
597
+ def erf(x, prec)
598
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :erf)
599
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :erf)
600
+ return BigDecimal::Internal.nan_computation_result if x.nan?
601
+ return BigDecimal(x.infinite?) if x.infinite?
602
+ return BigDecimal(0) if x == 0
603
+ return -erf(-x, prec) if x < 0
604
+ return BigDecimal(1) if x > 5000000000 # erf(5000000000) > 1 - 1e-10000000000000000000
605
+
606
+ if x > 8
607
+ xf = x.to_f
608
+ log10_erfc = -xf ** 2 / Math.log(10) - Math.log10(xf * Math::PI ** 0.5)
609
+ erfc_prec = [prec + log10_erfc.ceil, 1].max
610
+ erfc = _erfc_asymptotic(x, erfc_prec)
611
+ if erfc
612
+ # Workaround for https://github.com/ruby/bigdecimal/issues/464
613
+ return BigDecimal(1) if erfc.exponent < -prec - BigDecimal.double_fig
614
+
615
+ return BigDecimal(1).sub(erfc, prec)
616
+ end
617
+ end
618
+
619
+ prec2 = prec + BigDecimal.double_fig
620
+ x_smallprec = x.mult(1, Integer.sqrt(prec2) / 2)
621
+ # Taylor series of x with small precision is fast
622
+ erf1 = _erf_taylor(x_smallprec, BigDecimal(0), BigDecimal(0), prec2)
623
+ # Taylor series converges quickly for small x
624
+ _erf_taylor(x - x_smallprec, x_smallprec, erf1, prec2).mult(1, prec)
625
+ end
626
+
627
+ # call-seq:
628
+ # erfc(decimal, numeric) -> BigDecimal
629
+ #
630
+ # Computes the complementary error function of +decimal+ to the specified number of digits of
631
+ # precision, +numeric+.
632
+ #
633
+ # If +decimal+ is NaN, returns NaN.
634
+ #
635
+ # BigMath.erfc(BigDecimal('10'), 32).to_s
636
+ # #=> "0.20884875837625447570007862949578e-44"
637
+ #
638
+ def erfc(x, prec)
639
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :erfc)
640
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :erfc)
641
+ return BigDecimal::Internal.nan_computation_result if x.nan?
642
+ return BigDecimal(1 - x.infinite?) if x.infinite?
643
+ return BigDecimal(1).sub(erf(x, prec + BigDecimal.double_fig), prec) if x < 0
644
+ return BigDecimal(0) if x > 5000000000 # erfc(5000000000) < 1e-10000000000000000000 (underflow)
645
+
646
+ if x >= 8
647
+ y = _erfc_asymptotic(x, prec)
648
+ return y.mult(1, prec) if y
649
+ end
650
+
651
+ # erfc(x) = 1 - erf(x) < exp(-x**2)/x/sqrt(pi)
652
+ # Precision of erf(x) needs about log10(exp(-x**2)) extra digits
653
+ log10 = 2.302585092994046
654
+ high_prec = prec + BigDecimal.double_fig + (x.ceil**2 / log10).ceil
655
+ BigDecimal(1).sub(erf(x, high_prec), prec)
656
+ end
657
+
658
+ # Calculates erf(x + a)
659
+ private_class_method def _erf_taylor(x, a, erf_a, prec) # :nodoc:
660
+ return erf_a if x.zero?
661
+ # Let f(x+a) = erf(x+a)*exp((x+a)**2)*sqrt(pi)/2
662
+ # = c0 + c1*x + c2*x**2 + c3*x**3 + c4*x**4 + ...
663
+ # f'(x+a) = 1+2*(x+a)*f(x+a)
664
+ # f'(x+a) = c1 + 2*c2*x + 3*c3*x**2 + 4*c4*x**3 + 5*c5*x**4 + ...
665
+ # = 1+2*(x+a)*(c0 + c1*x + c2*x**2 + c3*x**3 + c4*x**4 + ...)
666
+ # therefore,
667
+ # c0 = f(a)
668
+ # c1 = 2 * a * c0 + 1
669
+ # c2 = (2 * c0 + 2 * a * c1) / 2
670
+ # c3 = (2 * c1 + 2 * a * c2) / 3
671
+ # c4 = (2 * c2 + 2 * a * c3) / 4
672
+ #
673
+ # All coefficients are positive when a >= 0
674
+
675
+ scale = BigDecimal(2).div(sqrt(PI(prec), prec), prec)
676
+ c_prev = erf_a.div(scale.mult(exp(-a*a, prec), prec), prec)
677
+ c_next = (2 * a * c_prev).add(1, prec).mult(x, prec)
678
+ sum = c_prev.add(c_next, prec)
679
+
680
+ 2.step do |k|
681
+ c = (c_prev.mult(x, prec) + a * c_next).mult(2, prec).mult(x, prec).div(k, prec)
682
+ sum = sum.add(c, prec)
683
+ c_prev, c_next = c_next, c
684
+ break if [c_prev, c_next].all? { |c| c.zero? || (c.exponent < sum.exponent - prec) }
685
+ end
686
+ value = sum.mult(scale.mult(exp(-(x + a).mult(x + a, prec), prec), prec), prec)
687
+ value > 1 ? BigDecimal(1) : value
688
+ end
689
+
690
+ private_class_method def _erfc_asymptotic(x, prec) # :nodoc:
691
+ # Let f(x) = erfc(x)*sqrt(pi)*exp(x**2)/2
692
+ # f(x) satisfies the following differential equation:
693
+ # 2*x*f(x) = f'(x) + 1
694
+ # From the above equation, we can derive the following asymptotic expansion:
695
+ # f(x) = (0..kmax).sum { (-1)**k * (2*k)! / 4**k / k! / x**(2*k)) } / x
696
+
697
+ # This asymptotic expansion does not converge.
698
+ # But if there is a k that satisfies (2*k)! / 4**k / k! / x**(2*k) < 10**(-prec),
699
+ # It is enough to calculate erfc within the given precision.
700
+ # Using Stirling's approximation, we can simplify this condition to:
701
+ # sqrt(2)/2 + k*log(k) - k - 2*k*log(x) < -prec*log(10)
702
+ # and the left side is minimized when k = x**2.
703
+ prec += BigDecimal.double_fig
704
+ xf = x.to_f
705
+ kmax = (1..(xf ** 2).floor).bsearch do |k|
706
+ Math.log(2) / 2 + k * Math.log(k) - k - 2 * k * Math.log(xf) < -prec * Math.log(10)
707
+ end
708
+ return unless kmax
709
+
710
+ sum = BigDecimal(1)
711
+ x2 = x.mult(x, prec)
712
+ d = BigDecimal(1)
713
+ (1..kmax).each do |k|
714
+ d = d.div(x2, prec).mult(1 - 2 * k, prec).div(2, prec)
715
+ sum = sum.add(d, prec)
716
+ end
717
+ sum.div(exp(x2, prec).mult(PI(prec).sqrt(prec), prec), prec).div(x, prec)
718
+ end
719
+
720
+ # call-seq:
721
+ # BigMath.gamma(decimal, numeric) -> BigDecimal
722
+ #
723
+ # Computes the gamma function of +decimal+ to the specified number of
724
+ # digits of precision, +numeric+.
725
+ #
726
+ # BigMath.gamma(BigDecimal('0.5'), 32).to_s
727
+ # #=> "0.17724538509055160272981674833411e1"
728
+ #
729
+ def gamma(x, prec)
730
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :gamma)
731
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :gamma)
732
+ prec2 = prec + BigDecimal.double_fig
733
+ if x < 0.5
734
+ raise Math::DomainError, 'Numerical argument is out of domain - gamma' if x.frac.zero?
735
+
736
+ # Euler's reflection formula: gamma(z) * gamma(1-z) = pi/sin(pi*z)
737
+ pi = PI(prec2)
738
+ sin = _sinpix(x, pi, prec2)
739
+ return pi.div(gamma(1 - x, prec2).mult(sin, prec2), prec)
740
+ elsif x.frac.zero? && x < 1000 * prec
741
+ return _gamma_positive_integer(x, prec2).mult(1, prec)
742
+ end
743
+
744
+ a, sum = _gamma_spouge_sum_part(x, prec2)
745
+ (x + (a - 1)).power(x - 0.5, prec2).mult(BigMath.exp(1 - x, prec2), prec2).mult(sum, prec)
746
+ end
747
+
748
+ # call-seq:
749
+ # BigMath.lgamma(decimal, numeric) -> [BigDecimal, Integer]
750
+ #
751
+ # Computes the natural logarithm of the absolute value of the gamma function
752
+ # of +decimal+ to the specified number of digits of precision, +numeric+ and its sign.
753
+ #
754
+ # BigMath.lgamma(BigDecimal('0.5'), 32)
755
+ # #=> [0.57236494292470008707171367567653e0, 1]
756
+ #
757
+ def lgamma(x, prec)
758
+ prec = BigDecimal::Internal.coerce_validate_prec(prec, :lgamma)
759
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :lgamma)
760
+ prec2 = prec + BigDecimal.double_fig
761
+ if x < 0.5
762
+ return [BigDecimal::INFINITY, 1] if x.frac.zero?
763
+
764
+ loop do
765
+ # Euler's reflection formula: gamma(z) * gamma(1-z) = pi/sin(pi*z)
766
+ pi = PI(prec2)
767
+ sin = _sinpix(x, pi, prec2)
768
+ log_gamma = BigMath.log(pi, prec2).sub(lgamma(1 - x, prec2).first + BigMath.log(sin.abs, prec2), prec)
769
+ return [log_gamma, sin > 0 ? 1 : -1] if prec2 + log_gamma.exponent > prec + BigDecimal.double_fig
770
+
771
+ # Retry with higher precision if loss of significance is too large
772
+ prec2 = prec2 * 3 / 2
773
+ end
774
+ elsif x.frac.zero? && x < 1000 * prec
775
+ log_gamma = BigMath.log(_gamma_positive_integer(x, prec2), prec)
776
+ [log_gamma, 1]
777
+ else
778
+ # if x is close to 1 or 2, increase precision to reduce loss of significance
779
+ diff1_exponent = (x - 1).exponent
780
+ diff2_exponent = (x - 2).exponent
781
+ extra_prec = [-diff1_exponent, -diff2_exponent, 0].max
782
+ extremely_near_one = diff1_exponent < -prec2
783
+ extremely_near_two = diff2_exponent < -prec2
784
+
785
+ if extremely_near_one || extremely_near_two
786
+ # If x is extreamely close to base = 1 or 2, linear interpolation is accurate enough.
787
+ # Taylor expansion at x = base is: (x - base) * digamma(base) + (x - base) ** 2 * trigamma(base) / 2 + ...
788
+ # And we can ignore (x - base) ** 2 and higher order terms.
789
+ base = extremely_near_one ? 1 : 2
790
+ d = BigDecimal(1)._decimal_shift(1 - prec2)
791
+ log_gamma_d, sign = lgamma(base + d, prec2)
792
+ return [log_gamma_d.mult(x - base, prec2).div(d, prec), sign]
793
+ end
794
+
795
+ prec2 += [-diff1_exponent, -diff2_exponent, 0].max
796
+ a, sum = _gamma_spouge_sum_part(x, prec2)
797
+ log_gamma = BigMath.log(sum, prec2).add((x - 0.5).mult(BigMath.log(x.add(a - 1, prec2), prec2), prec2) + 1 - x, prec)
798
+ [log_gamma, 1]
799
+ end
800
+ end
801
+
802
+ # Returns sum part: sqrt(2*pi) and c[k]/(x+k) terms of Spouge's approximation
803
+ private_class_method def _gamma_spouge_sum_part(x, prec) # :nodoc:
804
+ x -= 1
805
+ # Spouge's approximation
806
+ # x! = (x + a)**(x + 0.5) * exp(-x - a) * (sqrt(2 * pi) + (1..a - 1).sum{|k| c[k] / (x + k) } + epsilon)
807
+ # where c[k] = (-1)**k * (a - k)**(k - 0.5) * exp(a - k) / (k - 1)!
808
+ # and epsilon is bounded by a**(-0.5) * (2 * pi) ** (-a - 0.5)
809
+
810
+ # Estimate required a for given precision
811
+ a = (prec / Math.log10(2 * Math::PI)).ceil
812
+
813
+ # Calculate exponent of c[k] in low precision to estimate required precision
814
+ low_prec = 16
815
+ log10f = Math.log(10)
816
+ x_low_prec = x.mult(1, low_prec)
817
+ loggamma_k = 0
818
+ ck_exponents = (1..a-1).map do |k|
819
+ loggamma_k += Math.log10(k - 1) if k > 1
820
+ -loggamma_k - k / log10f + (k - 0.5) * Math.log10(a - k) - BigMath.log10(x_low_prec.add(k, low_prec), low_prec)
821
+ end
822
+
823
+ # Estimate exponent of sum by Stirling's approximation
824
+ approx_sum_exponent = x < 1 ? -Math.log10(a) / 2 : Math.log10(2 * Math::PI) / 2 + x_low_prec.add(0.5, low_prec) * Math.log10(x_low_prec / x_low_prec.add(a, low_prec))
825
+
826
+ # Determine required precision of c[k]
827
+ prec2 = [ck_exponents.max.ceil - approx_sum_exponent.floor, 0].max + prec
828
+
829
+ einv = BigMath.exp(-1, prec2)
830
+ sum = (PI(prec) * 2).sqrt(prec).mult(BigMath.exp(-a, prec), prec)
831
+ y = BigDecimal(1)
832
+ (1..a - 1).each do |k|
833
+ # c[k] = (-1)**k * (a - k)**(k - 0.5) * exp(-k) / (k-1)! / (x + k)
834
+ y = y.div(1 - k, prec2) if k > 1
835
+ y = y.mult(einv, prec2)
836
+ z = y.mult(BigDecimal((a - k) ** k), prec2).div(BigDecimal(a - k).sqrt(prec2).mult(x.add(k, prec2), prec2), prec2)
837
+ # sum += c[k] / (x + k)
838
+ sum = sum.add(z, prec2)
839
+ end
840
+ [a, sum]
841
+ end
842
+
843
+ private_class_method def _gamma_positive_integer(x, prec) # :nodoc:
844
+ return x if x == 1
845
+ numbers = (1..x - 1).map {|i| BigDecimal(i) }
846
+ while numbers.size > 1
847
+ numbers = numbers.each_slice(2).map {|a, b| b ? a.mult(b, prec) : a }
848
+ end
849
+ numbers.first
850
+ end
851
+
852
+ # Returns sin(pi * x), for gamma reflection formula calculation
853
+ private_class_method def _sinpix(x, pi, prec) # :nodoc:
854
+ x = x % 2
855
+ sign = x > 1 ? -1 : 1
856
+ x %= 1
857
+ x = 1 - x if x > 0.5 # to avoid sin(pi*x) loss of precision for x close to 1
858
+ sign * sin(x.mult(pi, prec), prec)
859
+ end
860
+
861
+ # call-seq:
862
+ # frexp(x) -> [BigDecimal, Integer]
863
+ #
864
+ # Decomposes +x+ into a normalized fraction and an integral power of ten.
865
+ #
866
+ # BigMath.frexp(BigDecimal(123.456))
867
+ # #=> [0.123456e0, 3]
868
+ #
869
+ def frexp(x)
870
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, 0, :frexp)
871
+ return [x, 0] unless x.finite?
872
+
873
+ exponent = x.exponent
874
+ [x._decimal_shift(-exponent), exponent]
875
+ end
876
+
877
+ # call-seq:
878
+ # ldexp(fraction, exponent) -> BigDecimal
879
+ #
880
+ # Inverse of +frexp+.
881
+ # Returns the value of fraction * 10**exponent.
882
+ #
883
+ # BigMath.ldexp(BigDecimal("0.123456e0"), 3)
884
+ # #=> 0.123456e3
885
+ #
886
+ def ldexp(x, exponent)
887
+ x = BigDecimal::Internal.coerce_to_bigdecimal(x, 0, :ldexp)
888
+ x.finite? ? x._decimal_shift(exponent) : x
889
+ end
890
+
191
891
  # call-seq:
192
892
  # PI(numeric) -> BigDecimal
193
893
  #
@@ -244,6 +944,6 @@ module BigMath
244
944
  #
245
945
  def E(prec)
246
946
  prec = BigDecimal::Internal.coerce_validate_prec(prec, :E)
247
- BigMath.exp(1, prec)
947
+ exp(1, prec)
248
948
  end
249
949
  end
@@ -2,6 +2,8 @@
2
2
  require "bigdecimal/ludcmp"
3
3
  require "bigdecimal/jacobian"
4
4
 
5
+ warn "'bigdecimal/newton' is deprecated and will be removed in a future release."
6
+
5
7
  #
6
8
  # newton.rb
7
9
  #
data/lib/bigdecimal.rb CHANGED
@@ -144,10 +144,10 @@ class BigDecimal
144
144
  return BigDecimal(1)
145
145
  end
146
146
 
147
- prec = BigDecimal.limit if prec.zero?
147
+ limit = BigDecimal.limit
148
148
  frac_part = y.frac
149
149
 
150
- if frac_part.zero? && prec.zero?
150
+ if frac_part.zero? && prec.zero? && limit.zero?
151
151
  # Infinite precision calculation for `x ** int` and `x.power(int)`
152
152
  int_part = y.fix.to_i
153
153
  int_part = -int_part if (neg = int_part < 0)
@@ -167,18 +167,19 @@ class BigDecimal
167
167
  return neg ? BigDecimal(1) / ans : ans
168
168
  end
169
169
 
170
- prec = [x.n_significant_digits, y.n_significant_digits, BigDecimal.double_fig].max + BigDecimal.double_fig if prec.zero?
170
+ result_prec = prec.nonzero? || [x.n_significant_digits, y.n_significant_digits, BigDecimal.double_fig].max + BigDecimal.double_fig
171
+ result_prec = [result_prec, limit].min if prec.zero? && limit.nonzero?
172
+
173
+ prec2 = result_prec + BigDecimal.double_fig
171
174
 
172
175
  if y < 0
173
- inv = x.power(-y, prec)
176
+ inv = x.power(-y, prec2)
174
177
  return BigDecimal(0) if inv.infinite?
175
178
  return BigDecimal::Internal.infinity_computation_result if inv.zero?
176
- return BigDecimal(1).div(inv, prec)
179
+ return BigDecimal(1).div(inv, result_prec)
177
180
  end
178
181
 
179
- prec2 = prec + BigDecimal.double_fig
180
-
181
- if frac_part.zero? && y.exponent < Math.log(prec) * 5 + 20
182
+ if frac_part.zero? && y.exponent < Math.log(result_prec) * 5 + 20
182
183
  # Use exponentiation by squaring if y is an integer and not too large
183
184
  pow_prec = prec2 + y.exponent
184
185
  n = 1
@@ -191,16 +192,16 @@ class BigDecimal
191
192
  break if n > int_part
192
193
  xn = xn.mult(xn, pow_prec)
193
194
  end
194
- ans.mult(1, prec)
195
+ ans.mult(1, result_prec)
195
196
  else
196
- if x > 1
197
+ if x > 1 && x.finite?
197
198
  # To calculate exp(z, prec), z needs prec+max(z.exponent, 0) precision if z > 0.
198
199
  # Estimate (y*log(x)).exponent
199
200
  logx_exponent = x < 2 ? (x - 1).exponent : Math.log10(x.exponent).round
200
201
  ylogx_exponent = y.exponent + logx_exponent
201
202
  prec2 += [ylogx_exponent, 0].max
202
203
  end
203
- BigMath.exp(BigMath.log(x, prec2).mult(y, prec2), prec)
204
+ BigMath.exp(BigMath.log(x, prec2).mult(y, prec2), result_prec)
204
205
  end
205
206
  end
206
207
 
@@ -217,7 +218,9 @@ class BigDecimal
217
218
  return self if zero?
218
219
 
219
220
  if prec == 0
220
- prec = BigDecimal.limit.nonzero? || n_significant_digits + BigDecimal.double_fig
221
+ limit = BigDecimal.limit
222
+ prec = n_significant_digits + BigDecimal.double_fig
223
+ prec = [limit, prec].min if limit.nonzero?
221
224
  end
222
225
 
223
226
  ex = exponent / 2
@@ -235,6 +238,7 @@ end
235
238
  # Core BigMath methods for BigDecimal (log, exp) are defined here.
236
239
  # Other methods (sin, cos, atan) are defined in 'bigdecimal/math.rb'.
237
240
  module BigMath
241
+ module_function
238
242
 
239
243
  # call-seq:
240
244
  # BigMath.log(decimal, numeric) -> BigDecimal
@@ -248,7 +252,7 @@ module BigMath
248
252
  #
249
253
  # If +decimal+ is NaN, returns NaN.
250
254
  #
251
- def self.log(x, prec)
255
+ def log(x, prec)
252
256
  prec = BigDecimal::Internal.coerce_validate_prec(prec, :log)
253
257
  raise Math::DomainError, 'Complex argument for BigMath.log' if Complex === x
254
258
 
@@ -303,7 +307,7 @@ module BigMath
303
307
  end
304
308
 
305
309
  # Taylor series for exp(x) around 0
306
- private_class_method def self._exp_taylor(x, prec) # :nodoc:
310
+ private_class_method def _exp_taylor(x, prec) # :nodoc:
307
311
  xn = BigDecimal(1)
308
312
  y = BigDecimal(1)
309
313
  1.step do |i|
@@ -325,7 +329,7 @@ module BigMath
325
329
  #
326
330
  # If +decimal+ is NaN, returns NaN.
327
331
  #
328
- def self.exp(x, prec)
332
+ def exp(x, prec)
329
333
  prec = BigDecimal::Internal.coerce_validate_prec(prec, :exp)
330
334
  x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :exp)
331
335
  return BigDecimal::Internal.nan_computation_result if x.nan?
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bigdecimal
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.1
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenta Murata
@@ -60,7 +60,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  requirements: []
63
- rubygems_version: 3.6.7
63
+ rubygems_version: 3.6.9
64
64
  specification_version: 4
65
65
  summary: Arbitrary-precision decimal floating-point number library.
66
66
  test_files: []