bigdecimal 1.4.4 → 2.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 87db143e2139576067ccfd911dde4e081aad19bc0faa08ca6b74a34c430e82de
4
- data.tar.gz: 54bde88f847fae9e241ec3817e96f45d21a8831b5827f76a0b25915b576d0900
3
+ metadata.gz: ef063cb7c648ba239e4179669ed4d410d9d160e293377ce4b1bdb73ec68366cb
4
+ data.tar.gz: d0e2d57a69c624ba2ef446c52fc19f889721809e7f6933ed8f0db684e3f9c1a2
5
5
  SHA512:
6
- metadata.gz: 360aa77ae2daadf7ff173669e115b76038b17f233694b316b17a159bec27be4eb1c57adee88350e3e3bde27097257b6d3526e057a28f5a4e457864cceb3aec5a
7
- data.tar.gz: 4cbb886e60336b3741f5f1cef0a29877384f1e51b49aee13a18d1afd4f4cea3b86a826cb1ee2923f23684a148334c9ec0a09bef620b29eb62283baa299b45366
6
+ metadata.gz: a7fa4a273ccddcdc65fd477b8ff59abde5951966b45ea43b78b257eb69e10a3dece8f62cb37d34b68f02201fcf0e2e2d471b835660ddb4bab9a1e1bc74d7c22b
7
+ data.tar.gz: 3a2de54bf09de5ffc15f31227a1458ad670ddccefa716e48c06ca4f98709d4de068f72be0be603c9e5bf60191b91a54f1e13ef617bdde833e98740c6ad34faf9
data/bigdecimal.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  # coding: utf-8
2
2
 
3
- bigdecimal_version = '1.4.4'
3
+ bigdecimal_version = '2.0.3'
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "bigdecimal"
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
11
11
  s.summary = "Arbitrary-precision decimal floating-point number library."
12
12
  s.description = "This library provides arbitrary-precision decimal floating-point number class."
13
13
  s.homepage = "https://github.com/ruby/bigdecimal"
14
- s.license = "ruby"
14
+ s.license = "Ruby"
15
15
 
16
16
  s.require_paths = %w[lib]
17
17
  s.extensions = %w[ext/bigdecimal/extconf.rb]
@@ -30,11 +30,10 @@ Gem::Specification.new do |s|
30
30
  sample/pi.rb
31
31
  ]
32
32
 
33
- s.required_ruby_version = Gem::Requirement.new(">= 2.3.0".freeze)
33
+ s.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
34
34
 
35
- s.add_development_dependency "rake", "~> 10.0"
35
+ s.add_development_dependency "rake", ">= 12.3.3"
36
36
  s.add_development_dependency "rake-compiler", ">= 0.9"
37
- s.add_development_dependency "rake-compiler-dock", ">= 0.6.1"
38
37
  s.add_development_dependency "minitest", "< 5.0.0"
39
38
  s.add_development_dependency "pry"
40
39
  end
@@ -14,6 +14,7 @@
14
14
  #include "ruby/util.h"
15
15
 
16
16
  #ifndef BIGDECIMAL_DEBUG
17
+ # undef NDEBUG
17
18
  # define NDEBUG
18
19
  #endif
19
20
  #include <assert.h>
@@ -24,7 +25,6 @@
24
25
  #include <string.h>
25
26
  #include <errno.h>
26
27
  #include <math.h>
27
- #include "math.h"
28
28
 
29
29
  #ifdef HAVE_IEEEFP_H
30
30
  #include <ieeefp.h>
@@ -77,7 +77,7 @@ static ID id_half;
77
77
  #define BASE1 (BASE/10)
78
78
 
79
79
  #ifndef DBLE_FIG
80
- #define DBLE_FIG (DBL_DIG+1) /* figure of double */
80
+ #define DBLE_FIG rmpd_double_figures() /* figure of double */
81
81
  #endif
82
82
 
83
83
  #ifndef RRATIONAL_ZERO_P
@@ -127,6 +127,30 @@ rb_rational_den(VALUE rat)
127
127
  }
128
128
  #endif
129
129
 
130
+ #ifndef HAVE_RB_COMPLEX_REAL
131
+ static inline VALUE
132
+ rb_complex_real(VALUE cmp)
133
+ {
134
+ #ifdef HAVE_TYPE_STRUCT_RCOMPLEX
135
+ return RCOMPLEX(cmp)->real;
136
+ #else
137
+ return rb_funcall(cmp, rb_intern("real"), 0);
138
+ #endif
139
+ }
140
+ #endif
141
+
142
+ #ifndef HAVE_RB_COMPLEX_IMAG
143
+ static inline VALUE
144
+ rb_complex_imag(VALUE cmp)
145
+ {
146
+ #ifdef HAVE_TYPE_STRUCT_RCOMPLEX
147
+ return RCOMPLEX(cmp)->imag;
148
+ #else
149
+ return rb_funcall(cmp, rb_intern("imag"), 0);
150
+ #endif
151
+ }
152
+ #endif
153
+
130
154
  #define BIGDECIMAL_POSITIVE_P(bd) ((bd)->sign > 0)
131
155
  #define BIGDECIMAL_NEGATIVE_P(bd) ((bd)->sign < 0)
132
156
 
@@ -228,7 +252,7 @@ again:
228
252
  switch(TYPE(v)) {
229
253
  case T_FLOAT:
230
254
  if (prec < 0) goto unable_to_coerce_without_prec;
231
- if (prec > DBL_DIG+1) goto SomeOneMayDoIt;
255
+ if (prec > (long)DBLE_FIG) goto SomeOneMayDoIt;
232
256
  d = RFLOAT_VALUE(v);
233
257
  if (!isfinite(d)) {
234
258
  pv = VpCreateRbObject(1, NULL);
@@ -276,7 +300,6 @@ again:
276
300
  #ifdef ENABLE_NUMERIC_STRING
277
301
  case T_STRING:
278
302
  StringValueCStr(v);
279
- rb_check_safe_obj(v);
280
303
  return VpCreateRbObject(RSTRING_LEN(v) + VpBaseFig() + 1,
281
304
  RSTRING_PTR(v));
282
305
  #endif /* ENABLE_NUMERIC_STRING */
@@ -327,11 +350,13 @@ BigDecimal_double_fig(VALUE self)
327
350
  /* call-seq:
328
351
  * big_decimal.precs -> array
329
352
  *
330
- * Returns an Array of two Integer values.
353
+ * Returns an Array of two Integer values that represent platform-dependent
354
+ * internal storage properties.
331
355
  *
332
- * The first value is the current number of significant digits in the
333
- * BigDecimal. The second value is the maximum number of significant digits
334
- * for the BigDecimal.
356
+ * This method is deprecated and will be removed in the future.
357
+ * Instead, use BigDecimal#n_significant_digits for obtaining the number of
358
+ * significant digits in scientific notation, and BigDecimal#precision for
359
+ * obtaining the number of digits in decimal notation.
335
360
  *
336
361
  * BigDecimal('5').precs #=> [9, 18]
337
362
  */
@@ -343,12 +368,109 @@ BigDecimal_prec(VALUE self)
343
368
  Real *p;
344
369
  VALUE obj;
345
370
 
371
+ rb_category_warn(RB_WARN_CATEGORY_DEPRECATED,
372
+ "BigDecimal#precs is deprecated and will be removed in the future; "
373
+ "use BigDecimal#precision instead.");
374
+
346
375
  GUARD_OBJ(p, GetVpValue(self, 1));
347
- obj = rb_assoc_new(INT2NUM(p->Prec*VpBaseFig()),
348
- INT2NUM(p->MaxPrec*VpBaseFig()));
376
+ obj = rb_assoc_new(SIZET2NUM(p->Prec*VpBaseFig()),
377
+ SIZET2NUM(p->MaxPrec*VpBaseFig()));
349
378
  return obj;
350
379
  }
351
380
 
381
+ /*
382
+ * call-seq:
383
+ * big_decimal.precision -> intreger
384
+ *
385
+ * Returns the number of decimal digits in this number.
386
+ *
387
+ * Example:
388
+ *
389
+ * BigDecimal("0").precision # => 0
390
+ * BigDecimal("1").precision # => 1
391
+ * BigDecimal("-1e20").precision # => 21
392
+ * BigDecimal("1e-20").precision # => 20
393
+ * BigDecimal("Infinity").precision # => 0
394
+ * BigDecimal("-Infinity").precision # => 0
395
+ * BigDecimal("NaN").precision # => 0
396
+ */
397
+ static VALUE
398
+ BigDecimal_precision(VALUE self)
399
+ {
400
+ ENTER(1);
401
+
402
+ Real *p;
403
+ GUARD_OBJ(p, GetVpValue(self, 1));
404
+
405
+ /*
406
+ * The most significant digit is frac[0], and the least significant digit is frac[Prec-1].
407
+ * When the exponent is zero, the decimal point is located just before frac[0].
408
+ * When the exponent is negative, the decimal point moves to leftward.
409
+ * Conversely, when the exponent is positive, the decimal point moves to rightward.
410
+ *
411
+ * | frac[0] frac[1] frac[2] . frac[3] frac[4] ... frac[Prec-1]
412
+ * |------------------------> exponent == 3
413
+ */
414
+
415
+ ssize_t ex = p->exponent;
416
+ ssize_t precision;
417
+ if (ex < 0) {
418
+ precision = (-ex + 1) * BASE_FIG; /* 1 is for p->frac[0] */
419
+ ex = 0;
420
+ }
421
+ else if (p->Prec > 0) {
422
+ BDIGIT x = p->frac[0];
423
+ for (precision = 0; x > 0; x /= 10) {
424
+ ++precision;
425
+ }
426
+ }
427
+
428
+ if (ex > (ssize_t)p->Prec) {
429
+ precision += (ex - 1) * BASE_FIG;
430
+ }
431
+ else if (p->Prec > 0) {
432
+ ssize_t n = (ssize_t)p->Prec - 1;
433
+ while (n > 0 && p->frac[n] == 0) --n;
434
+
435
+ precision += n * BASE_FIG;
436
+
437
+ if (ex < (ssize_t)p->Prec) {
438
+ BDIGIT x = p->frac[n];
439
+ for (; x > 0 && x % 10 == 0; x /= 10) {
440
+ --precision;
441
+ }
442
+ }
443
+ }
444
+
445
+ return SSIZET2NUM(precision);
446
+ }
447
+
448
+ static VALUE
449
+ BigDecimal_n_significant_digits(VALUE self)
450
+ {
451
+ ENTER(1);
452
+
453
+ Real *p;
454
+ GUARD_OBJ(p, GetVpValue(self, 1));
455
+
456
+ ssize_t n = p->Prec;
457
+ while (n > 0 && p->frac[n-1] == 0) --n;
458
+ if (n <= 0) {
459
+ return INT2FIX(0);
460
+ }
461
+
462
+ int nlz, ntz;
463
+
464
+ BDIGIT x = p->frac[0];
465
+ for (nlz = BASE_FIG; x > 0; x /= 10) --nlz;
466
+
467
+ x = p->frac[n-1];
468
+ for (ntz = 0; x > 0 && x % 10 == 0; x /= 10) ++ntz;
469
+
470
+ ssize_t n_digits = BASE_FIG * n - nlz - ntz;
471
+ return SSIZET2NUM(n_digits);
472
+ }
473
+
352
474
  /*
353
475
  * call-seq: hash
354
476
  *
@@ -418,7 +540,6 @@ BigDecimal_load(VALUE self, VALUE str)
418
540
  unsigned long m=0;
419
541
 
420
542
  pch = (unsigned char *)StringValueCStr(str);
421
- rb_check_safe_obj(str);
422
543
  /* First get max prec */
423
544
  while((*pch) != (unsigned char)'\0' && (ch = *pch++) != (unsigned char)':') {
424
545
  if(!ISDIGIT(ch)) {
@@ -877,7 +998,7 @@ BigDecimal_coerce(VALUE self, VALUE other)
877
998
  Real *b;
878
999
 
879
1000
  if (RB_TYPE_P(other, T_FLOAT)) {
880
- GUARD_OBJ(b, GetVpValueWithPrec(other, DBL_DIG+1, 1));
1001
+ GUARD_OBJ(b, GetVpValueWithPrec(other, DBLE_FIG, 1));
881
1002
  obj = rb_assoc_new(ToValue(b), self);
882
1003
  }
883
1004
  else {
@@ -935,7 +1056,7 @@ BigDecimal_add(VALUE self, VALUE r)
935
1056
 
936
1057
  GUARD_OBJ(a, GetVpValue(self, 1));
937
1058
  if (RB_TYPE_P(r, T_FLOAT)) {
938
- b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
1059
+ b = GetVpValueWithPrec(r, DBLE_FIG, 1);
939
1060
  }
940
1061
  else if (RB_TYPE_P(r, T_RATIONAL)) {
941
1062
  b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
@@ -993,7 +1114,7 @@ BigDecimal_sub(VALUE self, VALUE r)
993
1114
 
994
1115
  GUARD_OBJ(a, GetVpValue(self,1));
995
1116
  if (RB_TYPE_P(r, T_FLOAT)) {
996
- b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
1117
+ b = GetVpValueWithPrec(r, DBLE_FIG, 1);
997
1118
  }
998
1119
  else if (RB_TYPE_P(r, T_RATIONAL)) {
999
1120
  b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
@@ -1043,7 +1164,7 @@ BigDecimalCmp(VALUE self, VALUE r,char op)
1043
1164
  break;
1044
1165
 
1045
1166
  case T_FLOAT:
1046
- GUARD_OBJ(b, GetVpValueWithPrec(r, DBL_DIG+1, 0));
1167
+ GUARD_OBJ(b, GetVpValueWithPrec(r, DBLE_FIG, 0));
1047
1168
  break;
1048
1169
 
1049
1170
  case T_RATIONAL:
@@ -1256,7 +1377,7 @@ BigDecimal_mult(VALUE self, VALUE r)
1256
1377
 
1257
1378
  GUARD_OBJ(a, GetVpValue(self, 1));
1258
1379
  if (RB_TYPE_P(r, T_FLOAT)) {
1259
- b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
1380
+ b = GetVpValueWithPrec(r, DBLE_FIG, 1);
1260
1381
  }
1261
1382
  else if (RB_TYPE_P(r, T_RATIONAL)) {
1262
1383
  b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
@@ -1284,7 +1405,7 @@ BigDecimal_divide(Real **c, Real **res, Real **div, VALUE self, VALUE r)
1284
1405
 
1285
1406
  GUARD_OBJ(a, GetVpValue(self, 1));
1286
1407
  if (RB_TYPE_P(r, T_FLOAT)) {
1287
- b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
1408
+ b = GetVpValueWithPrec(r, DBLE_FIG, 1);
1288
1409
  }
1289
1410
  else if (RB_TYPE_P(r, T_RATIONAL)) {
1290
1411
  b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
@@ -1350,7 +1471,7 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod)
1350
1471
 
1351
1472
  GUARD_OBJ(a, GetVpValue(self, 1));
1352
1473
  if (RB_TYPE_P(r, T_FLOAT)) {
1353
- b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
1474
+ b = GetVpValueWithPrec(r, DBLE_FIG, 1);
1354
1475
  }
1355
1476
  else if (RB_TYPE_P(r, T_RATIONAL)) {
1356
1477
  b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
@@ -1451,7 +1572,7 @@ BigDecimal_divremain(VALUE self, VALUE r, Real **dv, Real **rv)
1451
1572
 
1452
1573
  GUARD_OBJ(a, GetVpValue(self, 1));
1453
1574
  if (RB_TYPE_P(r, T_FLOAT)) {
1454
- b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
1575
+ b = GetVpValueWithPrec(r, DBLE_FIG, 1);
1455
1576
  }
1456
1577
  else if (RB_TYPE_P(r, T_RATIONAL)) {
1457
1578
  b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
@@ -1756,20 +1877,23 @@ BigDecimal_fix(VALUE self)
1756
1877
  * round(n, mode)
1757
1878
  *
1758
1879
  * Round to the nearest integer (by default), returning the result as a
1759
- * BigDecimal.
1880
+ * BigDecimal if n is specified, or as an Integer if it isn't.
1760
1881
  *
1761
1882
  * BigDecimal('3.14159').round #=> 3
1762
1883
  * BigDecimal('8.7').round #=> 9
1763
1884
  * BigDecimal('-9.9').round #=> -10
1764
1885
  *
1886
+ * BigDecimal('3.14159').round(2).class.name #=> "BigDecimal"
1887
+ * BigDecimal('3.14159').round.class.name #=> "Integer"
1888
+ *
1765
1889
  * If n is specified and positive, the fractional part of the result has no
1766
1890
  * more than that many digits.
1767
1891
  *
1768
1892
  * If n is specified and negative, at least that many digits to the left of the
1769
- * decimal point will be 0 in the result.
1893
+ * decimal point will be 0 in the result, and return value will be an Integer.
1770
1894
  *
1771
1895
  * BigDecimal('3.14159').round(3) #=> 3.142
1772
- * BigDecimal('13345.234').round(-2) #=> 13300.0
1896
+ * BigDecimal('13345.234').round(-2) #=> 13300
1773
1897
  *
1774
1898
  * The value of the optional mode argument can be used to determine how
1775
1899
  * rounding is performed; see BigDecimal.mode.
@@ -1782,6 +1906,7 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
1782
1906
  int iLoc = 0;
1783
1907
  VALUE vLoc;
1784
1908
  VALUE vRound;
1909
+ int round_to_int = 0;
1785
1910
  size_t mx, pl;
1786
1911
 
1787
1912
  unsigned short sw = VpGetRoundMode();
@@ -1789,6 +1914,7 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
1789
1914
  switch (rb_scan_args(argc, argv, "02", &vLoc, &vRound)) {
1790
1915
  case 0:
1791
1916
  iLoc = 0;
1917
+ round_to_int = 1;
1792
1918
  break;
1793
1919
  case 1:
1794
1920
  if (RB_TYPE_P(vLoc, T_HASH)) {
@@ -1796,6 +1922,7 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
1796
1922
  }
1797
1923
  else {
1798
1924
  iLoc = NUM2INT(vLoc);
1925
+ if (iLoc < 1) round_to_int = 1;
1799
1926
  }
1800
1927
  break;
1801
1928
  case 2:
@@ -1817,7 +1944,7 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
1817
1944
  GUARD_OBJ(c, VpCreateRbObject(mx, "0"));
1818
1945
  VpSetPrecLimit(pl);
1819
1946
  VpActiveRound(c, a, sw, iLoc);
1820
- if (argc == 0) {
1947
+ if (round_to_int) {
1821
1948
  return BigDecimal_to_i(ToValue(c));
1822
1949
  }
1823
1950
  return ToValue(c);
@@ -2027,7 +2154,6 @@ BigDecimal_to_s(int argc, VALUE *argv, VALUE self)
2027
2154
  if (rb_scan_args(argc, argv, "01", &f) == 1) {
2028
2155
  if (RB_TYPE_P(f, T_STRING)) {
2029
2156
  psz = StringValueCStr(f);
2030
- rb_check_safe_obj(f);
2031
2157
  if (*psz == ' ') {
2032
2158
  fPlus = 1;
2033
2159
  psz++;
@@ -2067,7 +2193,7 @@ BigDecimal_to_s(int argc, VALUE *argv, VALUE self)
2067
2193
  nc += (nc + mc - 1) / mc + 1;
2068
2194
  }
2069
2195
 
2070
- str = rb_str_new(0, nc);
2196
+ str = rb_usascii_str_new(0, nc);
2071
2197
  psz = RSTRING_PTR(str);
2072
2198
 
2073
2199
  if (fmt) {
@@ -2132,7 +2258,7 @@ BigDecimal_split(VALUE self)
2132
2258
  rb_ary_push(obj, str);
2133
2259
  rb_str_resize(str, strlen(psz1));
2134
2260
  rb_ary_push(obj, INT2FIX(10));
2135
- rb_ary_push(obj, INT2NUM(e));
2261
+ rb_ary_push(obj, SSIZET2NUM(e));
2136
2262
  return obj;
2137
2263
  }
2138
2264
 
@@ -2145,7 +2271,7 @@ static VALUE
2145
2271
  BigDecimal_exponent(VALUE self)
2146
2272
  {
2147
2273
  ssize_t e = VpExponent10(GetVpValue(self, 1));
2148
- return INT2NUM(e);
2274
+ return SSIZET2NUM(e);
2149
2275
  }
2150
2276
 
2151
2277
  /* Returns a string representation of self.
@@ -2338,7 +2464,10 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
2338
2464
  }
2339
2465
  goto retry;
2340
2466
  }
2341
- exp = GetVpValueWithPrec(vexp, DBL_DIG+1, 1);
2467
+ if (NIL_P(prec)) {
2468
+ n += DBLE_FIG;
2469
+ }
2470
+ exp = GetVpValueWithPrec(vexp, DBLE_FIG, 1);
2342
2471
  break;
2343
2472
 
2344
2473
  case T_RATIONAL:
@@ -2353,6 +2482,9 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
2353
2482
  goto retry;
2354
2483
  }
2355
2484
  exp = GetVpValueWithPrec(vexp, n, 1);
2485
+ if (NIL_P(prec)) {
2486
+ n += n;
2487
+ }
2356
2488
  break;
2357
2489
 
2358
2490
  case T_DATA:
@@ -2363,6 +2495,10 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
2363
2495
  vexp = BigDecimal_to_i(vexp);
2364
2496
  goto retry;
2365
2497
  }
2498
+ if (NIL_P(prec)) {
2499
+ GUARD_OBJ(y, GetVpValue(vexp, 1));
2500
+ n += y->Prec*VpBaseFig();
2501
+ }
2366
2502
  exp = DATA_PTR(vexp);
2367
2503
  break;
2368
2504
  }
@@ -2560,6 +2696,10 @@ BigDecimal_clone(VALUE self)
2560
2696
  return self;
2561
2697
  }
2562
2698
 
2699
+ #ifdef HAVE_RB_OPTS_EXCEPTION_P
2700
+ int rb_opts_exception_p(VALUE opts, int default_value);
2701
+ #define opts_exception_p(opts) rb_opts_exception_p((opts), 1)
2702
+ #else
2563
2703
  static int
2564
2704
  opts_exception_p(VALUE opts)
2565
2705
  {
@@ -2568,12 +2708,20 @@ opts_exception_p(VALUE opts)
2568
2708
  if (!kwds[0]) {
2569
2709
  kwds[0] = rb_intern_const("exception");
2570
2710
  }
2571
- rb_get_kwargs(opts, kwds, 0, 1, &exception);
2711
+ if (!rb_get_kwargs(opts, kwds, 0, 1, &exception)) return 1;
2712
+ switch (exception) {
2713
+ case Qtrue: case Qfalse:
2714
+ break;
2715
+ default:
2716
+ rb_raise(rb_eArgError, "true or false is expected as exception: %+"PRIsVALUE,
2717
+ exception);
2718
+ }
2572
2719
  return exception != Qfalse;
2573
2720
  }
2721
+ #endif
2574
2722
 
2575
2723
  static Real *
2576
- VpNewVarArgs(int argc, VALUE *argv)
2724
+ VpNewVarArg(int argc, VALUE *argv)
2577
2725
  {
2578
2726
  size_t mf;
2579
2727
  VALUE opts = Qnil;
@@ -2616,6 +2764,7 @@ VpNewVarArgs(int argc, VALUE *argv)
2616
2764
  }
2617
2765
  }
2618
2766
 
2767
+ retry:
2619
2768
  switch (TYPE(iniValue)) {
2620
2769
  case T_DATA:
2621
2770
  if (is_kind_of_BigDecimal(iniValue)) {
@@ -2635,7 +2784,7 @@ VpNewVarArgs(int argc, VALUE *argv)
2635
2784
  VpDtoV(pv, d);
2636
2785
  return pv;
2637
2786
  }
2638
- if (mf > DBL_DIG+1) {
2787
+ if (mf > DBLE_FIG) {
2639
2788
  if (!exc) {
2640
2789
  return NULL;
2641
2790
  }
@@ -2653,6 +2802,18 @@ VpNewVarArgs(int argc, VALUE *argv)
2653
2802
  }
2654
2803
  return GetVpValueWithPrec(iniValue, mf, 1);
2655
2804
 
2805
+ case T_COMPLEX:
2806
+ {
2807
+ VALUE im;
2808
+ im = rb_complex_imag(iniValue);
2809
+ if (!is_zero(im)) {
2810
+ rb_raise(rb_eArgError,
2811
+ "Unable to make a BigDecimal from non-zero imaginary number");
2812
+ }
2813
+ iniValue = rb_complex_real(iniValue);
2814
+ goto retry;
2815
+ }
2816
+
2656
2817
  case T_STRING:
2657
2818
  /* fall through */
2658
2819
  default:
@@ -2667,23 +2828,6 @@ VpNewVarArgs(int argc, VALUE *argv)
2667
2828
  return VpAlloc(mf, RSTRING_PTR(iniValue), 1, exc);
2668
2829
  }
2669
2830
 
2670
- static VALUE
2671
- BigDecimal_new(int argc, VALUE *argv, VALUE klass)
2672
- {
2673
- ENTER(1);
2674
- Real *pv;
2675
- VALUE obj;
2676
-
2677
- obj = TypedData_Wrap_Struct(klass, &BigDecimal_data_type, 0);
2678
- pv = VpNewVarArgs(argc, argv);
2679
- if (pv == NULL) return Qnil;
2680
- SAVE(pv);
2681
- if (ToValue(pv)) pv = VpCopy(NULL, pv);
2682
- RTYPEDDATA_DATA(obj) = pv;
2683
- RB_OBJ_FREEZE(obj);
2684
- return pv->obj = obj;
2685
- }
2686
-
2687
2831
  /* call-seq:
2688
2832
  * BigDecimal(initial, digits, exception: true)
2689
2833
  *
@@ -2723,28 +2867,35 @@ BigDecimal_new(int argc, VALUE *argv, VALUE klass)
2723
2867
  static VALUE
2724
2868
  f_BigDecimal(int argc, VALUE *argv, VALUE self)
2725
2869
  {
2726
- return BigDecimal_new(argc, argv, rb_cBigDecimal);
2870
+ ENTER(1);
2871
+ Real *pv;
2872
+ VALUE obj;
2873
+
2874
+ if (argc > 0 && CLASS_OF(argv[0]) == rb_cBigDecimal) {
2875
+ if (argc == 1 || (argc == 2 && RB_TYPE_P(argv[1], T_HASH))) return argv[0];
2876
+ }
2877
+ obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, 0);
2878
+ pv = VpNewVarArg(argc, argv);
2879
+ if (pv == NULL) return Qnil;
2880
+ SAVE(pv);
2881
+ if (ToValue(pv)) pv = VpCopy(NULL, pv);
2882
+ RTYPEDDATA_DATA(obj) = pv;
2883
+ RB_OBJ_FREEZE(obj);
2884
+ return pv->obj = obj;
2727
2885
  }
2728
2886
 
2729
2887
  static VALUE
2730
2888
  BigDecimal_s_interpret_loosely(VALUE klass, VALUE str)
2731
2889
  {
2732
- ENTER(1);
2733
- char const *c_str;
2734
- Real *pv;
2735
-
2736
- c_str = StringValueCStr(str);
2737
- GUARD_OBJ(pv, VpAlloc(0, c_str, 0, 1));
2738
- pv->obj = TypedData_Wrap_Struct(klass, &BigDecimal_data_type, pv);
2739
- RB_OBJ_FREEZE(pv->obj);
2740
- return pv->obj;
2741
- }
2890
+ ENTER(1);
2891
+ char const *c_str;
2892
+ Real *pv;
2742
2893
 
2743
- /* DEPRECATED: BigDecimal.new() */
2744
- static VALUE
2745
- BigDecimal_s_new(int argc, VALUE *argv, VALUE klass)
2746
- {
2747
- return BigDecimal_new(argc, argv, klass);
2894
+ c_str = StringValueCStr(str);
2895
+ GUARD_OBJ(pv, VpAlloc(0, c_str, 0, 1));
2896
+ pv->obj = TypedData_Wrap_Struct(klass, &BigDecimal_data_type, pv);
2897
+ RB_OBJ_FREEZE(pv->obj);
2898
+ return pv->obj;
2748
2899
  }
2749
2900
 
2750
2901
  /* call-seq:
@@ -2763,7 +2914,7 @@ static VALUE
2763
2914
  BigDecimal_limit(int argc, VALUE *argv, VALUE self)
2764
2915
  {
2765
2916
  VALUE nFig;
2766
- VALUE nCur = INT2NUM(VpGetPrecLimit());
2917
+ VALUE nCur = SIZET2NUM(VpGetPrecLimit());
2767
2918
 
2768
2919
  if (rb_scan_args(argc, argv, "01", &nFig) == 1) {
2769
2920
  int nf;
@@ -2928,7 +3079,7 @@ BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec)
2928
3079
  infinite = isinf(flo);
2929
3080
  nan = isnan(flo);
2930
3081
  if (!infinite && !nan) {
2931
- vx = GetVpValueWithPrec(x, DBL_DIG+1, 0);
3082
+ vx = GetVpValueWithPrec(x, DBLE_FIG, 0);
2932
3083
  }
2933
3084
  break;
2934
3085
 
@@ -2966,6 +3117,10 @@ BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec)
2966
3117
  n = prec + rmpd_double_figures();
2967
3118
  negative = BIGDECIMAL_NEGATIVE_P(vx);
2968
3119
  if (negative) {
3120
+ VALUE x_zero = INT2NUM(1);
3121
+ VALUE x_copy = f_BigDecimal(1, &x_zero, klass);
3122
+ x = BigDecimal_initialize_copy(x_copy, x);
3123
+ vx = DATA_PTR(x);
2969
3124
  VpSetSign(vx, 1);
2970
3125
  }
2971
3126
 
@@ -3077,7 +3232,7 @@ get_vp_value:
3077
3232
  infinite = isinf(flo);
3078
3233
  nan = isnan(flo);
3079
3234
  if (!zero && !negative && !infinite && !nan) {
3080
- vx = GetVpValueWithPrec(x, DBL_DIG+1, 1);
3235
+ vx = GetVpValueWithPrec(x, DBLE_FIG, 1);
3081
3236
  }
3082
3237
  break;
3083
3238
 
@@ -3311,9 +3466,9 @@ Init_bigdecimal(void)
3311
3466
  rb_define_global_function("BigDecimal", f_BigDecimal, -1);
3312
3467
 
3313
3468
  /* Class methods */
3314
- rb_undef_method(CLASS_OF(rb_cBigDecimal), "allocate");
3469
+ rb_undef_alloc_func(rb_cBigDecimal);
3470
+ rb_undef_method(CLASS_OF(rb_cBigDecimal), "new");
3315
3471
  rb_define_singleton_method(rb_cBigDecimal, "interpret_loosely", BigDecimal_s_interpret_loosely, 1);
3316
- rb_define_singleton_method(rb_cBigDecimal, "new", BigDecimal_s_new, -1);
3317
3472
  rb_define_singleton_method(rb_cBigDecimal, "mode", BigDecimal_mode, -1);
3318
3473
  rb_define_singleton_method(rb_cBigDecimal, "limit", BigDecimal_limit, -1);
3319
3474
  rb_define_singleton_method(rb_cBigDecimal, "double_fig", BigDecimal_double_fig, 0);
@@ -3444,8 +3599,9 @@ Init_bigdecimal(void)
3444
3599
 
3445
3600
 
3446
3601
  /* instance methods */
3447
- rb_define_method(rb_cBigDecimal, "initialize_copy", BigDecimal_initialize_copy, 1);
3448
3602
  rb_define_method(rb_cBigDecimal, "precs", BigDecimal_prec, 0);
3603
+ rb_define_method(rb_cBigDecimal, "precision", BigDecimal_precision, 0);
3604
+ rb_define_method(rb_cBigDecimal, "n_significant_digits", BigDecimal_n_significant_digits, 0);
3449
3605
 
3450
3606
  rb_define_method(rb_cBigDecimal, "add", BigDecimal_add2, 2);
3451
3607
  rb_define_method(rb_cBigDecimal, "sub", BigDecimal_sub2, 2);
@@ -3968,7 +4124,7 @@ VpNumOfChars(Real *vp,const char *pszFmt)
3968
4124
  * by one BDIGIT word in the computer used.
3969
4125
  *
3970
4126
  * [Returns]
3971
- * 1+DBL_DIG ... OK
4127
+ * DBLE_FIG ... OK
3972
4128
  */
3973
4129
  VP_EXPORT size_t
3974
4130
  VpInit(BDIGIT BaseVal)
@@ -4138,7 +4294,7 @@ VpAlloc(size_t mx, const char *szVal, int strict_p, int exc)
4138
4294
  /* at least mx digits. */
4139
4295
  /* szVal==NULL ==> allocate zero value. */
4140
4296
  vp = VpAllocReal(mx);
4141
- /* xmalloc() alway returns(or throw interruption) */
4297
+ /* xmalloc() always returns(or throw interruption) */
4142
4298
  vp->MaxPrec = mx; /* set max precision */
4143
4299
  VpSetZero(vp, 1); /* initialize vp to zero. */
4144
4300
  return vp;
@@ -4314,7 +4470,7 @@ VpAlloc(size_t mx, const char *szVal, int strict_p, int exc)
4314
4470
  nalloc = Max(nalloc, mx);
4315
4471
  mx = nalloc;
4316
4472
  vp = VpAllocReal(mx);
4317
- /* xmalloc() alway returns(or throw interruption) */
4473
+ /* xmalloc() always returns(or throw interruption) */
4318
4474
  vp->MaxPrec = mx; /* set max precision */
4319
4475
  VpSetZero(vp, sign);
4320
4476
  VpCtoV(vp, psz, ni, psz + ipf, nf, psz + ipe, ne);
@@ -159,6 +159,10 @@ rb_sym2str(VALUE sym)
159
159
  # define vabs llabs
160
160
  #endif
161
161
 
162
+ #if !defined(HAVE_RB_CATEGORY_WARN) || !defined(HAVE_CONST_RB_WARN_CATEGORY_DEPRECATED)
163
+ # define rb_category_warn(category, ...) rb_warn(__VA_ARGS__)
164
+ #endif
165
+
162
166
  extern VALUE rb_cBigDecimal;
163
167
 
164
168
  #if 0 || SIZEOF_BDIGITS >= 16
@@ -36,8 +36,14 @@ have_func("isfinite", "math.h")
36
36
  have_type("struct RRational", "ruby.h")
37
37
  have_func("rb_rational_num", "ruby.h")
38
38
  have_func("rb_rational_den", "ruby.h")
39
+ have_type("struct RComplex", "ruby.h")
40
+ have_func("rb_complex_real", "ruby.h")
41
+ have_func("rb_complex_imag", "ruby.h")
39
42
  have_func("rb_array_const_ptr", "ruby.h")
40
43
  have_func("rb_sym2str", "ruby.h")
44
+ have_func("rb_opts_exception_p", "ruby.h")
45
+ have_func("rb_category_warn", "ruby.h")
46
+ have_const("RB_WARN_CATEGORY_DEPRECATED", "ruby.h")
41
47
 
42
48
  if File.file?(File.expand_path('../lib/bigdecimal.rb', __FILE__))
43
49
  bigdecimal_rb = "$(srcdir)/lib/bigdecimal.rb"
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: false
2
- #
2
+
3
+ require 'bigdecimal'
4
+
3
5
  # require 'bigdecimal/jacobian'
4
6
  #
5
7
  # Provides methods to compute the Jacobian matrix of a set of equations at a
@@ -21,9 +23,6 @@
21
23
  #
22
24
  # fx is f.values(x).
23
25
  #
24
-
25
- require 'bigdecimal'
26
-
27
26
  module Jacobian
28
27
  module_function
29
28
 
@@ -43,7 +43,7 @@ class Float < Numeric
43
43
  #
44
44
  # See also BigDecimal::new.
45
45
  #
46
- def to_d(precision=Float::DIG)
46
+ def to_d(precision=Float::DIG+1)
47
47
  BigDecimal(self, precision)
48
48
  end
49
49
  end
@@ -131,6 +131,39 @@ class Rational < Numeric
131
131
  end
132
132
 
133
133
 
134
+ class Complex < Numeric
135
+ # call-seq:
136
+ # cmp.to_d -> bigdecimal
137
+ # cmp.to_d(precision) -> bigdecimal
138
+ #
139
+ # Returns the value as a BigDecimal.
140
+ #
141
+ # The +precision+ parameter is required for a rational complex number.
142
+ # This parameter is used to determine the number of significant digits
143
+ # for the result.
144
+ #
145
+ # require 'bigdecimal'
146
+ # require 'bigdecimal/util'
147
+ #
148
+ # Complex(0.1234567, 0).to_d(4) # => 0.1235e0
149
+ # Complex(Rational(22, 7), 0).to_d(3) # => 0.314e1
150
+ #
151
+ # See also BigDecimal::new.
152
+ #
153
+ def to_d(*args)
154
+ BigDecimal(self) unless self.imag.zero? # to raise eerror
155
+
156
+ if args.length == 0
157
+ case self.real
158
+ when Rational
159
+ BigDecimal(self.real) # to raise error
160
+ end
161
+ end
162
+ self.real.to_d(*args)
163
+ end
164
+ end
165
+
166
+
134
167
  class NilClass
135
168
  # call-seq:
136
169
  # nil.to_d -> bigdecimal
data/lib/bigdecimal.rb CHANGED
@@ -1,22 +1 @@
1
- begin
2
- require "#{RUBY_VERSION[/\d+\.\d+/]}/bigdecimal.so"
3
- rescue LoadError
4
- require 'bigdecimal.so'
5
- end
6
-
7
- class BigDecimal
8
- module Deprecation
9
- def new(*args, **kwargs)
10
- warn "BigDecimal.new is deprecated; use BigDecimal() method instead.", uplevel: 1
11
- super
12
- end
13
- end
14
-
15
- class << self
16
- prepend Deprecation
17
-
18
- def inherited(subclass)
19
- warn "subclassing BigDecimal will be disallowed after bigdecimal version 2.0", uplevel: 1
20
- end
21
- end
22
- end
1
+ require 'bigdecimal.so'
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: 1.4.4
4
+ version: 2.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenta Murata
@@ -10,22 +10,22 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2019-05-13 00:00:00.000000000 Z
13
+ date: 2020-12-19 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
17
17
  requirement: !ruby/object:Gem::Requirement
18
18
  requirements:
19
- - - "~>"
19
+ - - ">="
20
20
  - !ruby/object:Gem::Version
21
- version: '10.0'
21
+ version: 12.3.3
22
22
  type: :development
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
- - - "~>"
26
+ - - ">="
27
27
  - !ruby/object:Gem::Version
28
- version: '10.0'
28
+ version: 12.3.3
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: rake-compiler
31
31
  requirement: !ruby/object:Gem::Requirement
@@ -40,20 +40,6 @@ dependencies:
40
40
  - - ">="
41
41
  - !ruby/object:Gem::Version
42
42
  version: '0.9'
43
- - !ruby/object:Gem::Dependency
44
- name: rake-compiler-dock
45
- requirement: !ruby/object:Gem::Requirement
46
- requirements:
47
- - - ">="
48
- - !ruby/object:Gem::Version
49
- version: 0.6.1
50
- type: :development
51
- prerelease: false
52
- version_requirements: !ruby/object:Gem::Requirement
53
- requirements:
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- version: 0.6.1
57
43
  - !ruby/object:Gem::Dependency
58
44
  name: minitest
59
45
  requirement: !ruby/object:Gem::Requirement
@@ -106,7 +92,7 @@ files:
106
92
  - sample/pi.rb
107
93
  homepage: https://github.com/ruby/bigdecimal
108
94
  licenses:
109
- - ruby
95
+ - Ruby
110
96
  metadata: {}
111
97
  post_install_message:
112
98
  rdoc_options: []
@@ -116,14 +102,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
116
102
  requirements:
117
103
  - - ">="
118
104
  - !ruby/object:Gem::Version
119
- version: 2.3.0
105
+ version: 2.4.0
120
106
  required_rubygems_version: !ruby/object:Gem::Requirement
121
107
  requirements:
122
108
  - - ">="
123
109
  - !ruby/object:Gem::Version
124
110
  version: '0'
125
111
  requirements: []
126
- rubygems_version: 3.0.3
112
+ rubygems_version: 3.2.2
127
113
  signing_key:
128
114
  specification_version: 4
129
115
  summary: Arbitrary-precision decimal floating-point number library.