bigdecimal 2.0.2 → 3.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: f755d262f35a249de6848a00e3bf3b8d7a4816dc9a61bb81c099a22baa40bf66
4
- data.tar.gz: f3b06716476c5da9c8a8006b6aeca492ac0206bce305c23910280fe0a0b28de1
3
+ metadata.gz: 1b3519c64aa42c80e19107fc6d5d78d81385d7d71b9c09abef67c4e4c6a0bcef
4
+ data.tar.gz: 4ab9cb50f0a24014262635c07ecb42e6891326b49de50f262550e22d00c586ed
5
5
  SHA512:
6
- metadata.gz: 35be1b5d13ee12b4b40ab3cf7277fb235fffcaf554f71107fe3b0727bcef9edb6b03c02bd7db0039505a575752a8014f41402775e8080ec9da2dcda184787df5
7
- data.tar.gz: f4f063cc6cd0291cbac0f77b2fac485a1e064b08a8789e2ac7b796e6e36529a40a781783bc0417893e01985ad5fa37487c233e5da8fb88eb64c73774de2a9173
6
+ metadata.gz: 8e4aa6023012625b46f68a9e58d79a5ea0aa2c579ddb4245e0753a01118d62bd75fa5a708535346ab295619aa2ad9974a929189a83a00d56321c295a1ec8498c
7
+ data.tar.gz: 5717f808a7a56ae06b5060a3752fcaf3a9b47dca9dceb8e6822e603ec20f0296b711df04d1454a309ac6720d4af60e9b4e58f3477133f7a66e20eab75207a70e
@@ -1,6 +1,6 @@
1
1
  # coding: utf-8
2
2
 
3
- bigdecimal_version = '2.0.2'
3
+ bigdecimal_version = '3.0.0'
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "bigdecimal"
@@ -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
@@ -189,11 +189,16 @@ BigDecimal_memsize(const void *ptr)
189
189
  return (sizeof(*pv) + pv->MaxPrec * sizeof(BDIGIT));
190
190
  }
191
191
 
192
+ #ifndef HAVE_RB_EXT_RACTOR_SAFE
193
+ # undef RUBY_TYPED_FROZEN_SHAREABLE
194
+ # define RUBY_TYPED_FROZEN_SHAREABLE 0
195
+ #endif
196
+
192
197
  static const rb_data_type_t BigDecimal_data_type = {
193
198
  "BigDecimal",
194
199
  { 0, BigDecimal_delete, BigDecimal_memsize, },
195
200
  #ifdef RUBY_TYPED_FREE_IMMEDIATELY
196
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
201
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE
197
202
  #endif
198
203
  };
199
204
 
@@ -252,7 +257,7 @@ again:
252
257
  switch(TYPE(v)) {
253
258
  case T_FLOAT:
254
259
  if (prec < 0) goto unable_to_coerce_without_prec;
255
- if (prec > DBL_DIG+1) goto SomeOneMayDoIt;
260
+ if (prec > (long)DBLE_FIG) goto SomeOneMayDoIt;
256
261
  d = RFLOAT_VALUE(v);
257
262
  if (!isfinite(d)) {
258
263
  pv = VpCreateRbObject(1, NULL);
@@ -350,11 +355,13 @@ BigDecimal_double_fig(VALUE self)
350
355
  /* call-seq:
351
356
  * big_decimal.precs -> array
352
357
  *
353
- * Returns an Array of two Integer values.
358
+ * Returns an Array of two Integer values that represent platform-dependent
359
+ * internal storage properties.
354
360
  *
355
- * The first value is the current number of significant digits in the
356
- * BigDecimal. The second value is the maximum number of significant digits
357
- * for the BigDecimal.
361
+ * This method is deprecated and will be removed in the future.
362
+ * Instead, use BigDecimal#n_significant_digits for obtaining the number of
363
+ * significant digits in scientific notation, and BigDecimal#precision for
364
+ * obtaining the number of digits in decimal notation.
358
365
  *
359
366
  * BigDecimal('5').precs #=> [9, 18]
360
367
  */
@@ -366,12 +373,109 @@ BigDecimal_prec(VALUE self)
366
373
  Real *p;
367
374
  VALUE obj;
368
375
 
376
+ rb_category_warn(RB_WARN_CATEGORY_DEPRECATED,
377
+ "BigDecimal#precs is deprecated and will be removed in the future; "
378
+ "use BigDecimal#precision instead.");
379
+
369
380
  GUARD_OBJ(p, GetVpValue(self, 1));
370
381
  obj = rb_assoc_new(SIZET2NUM(p->Prec*VpBaseFig()),
371
382
  SIZET2NUM(p->MaxPrec*VpBaseFig()));
372
383
  return obj;
373
384
  }
374
385
 
386
+ /*
387
+ * call-seq:
388
+ * big_decimal.precision -> intreger
389
+ *
390
+ * Returns the number of decimal digits in this number.
391
+ *
392
+ * Example:
393
+ *
394
+ * BigDecimal("0").precision # => 0
395
+ * BigDecimal("1").precision # => 1
396
+ * BigDecimal("-1e20").precision # => 21
397
+ * BigDecimal("1e-20").precision # => 20
398
+ * BigDecimal("Infinity").precision # => 0
399
+ * BigDecimal("-Infinity").precision # => 0
400
+ * BigDecimal("NaN").precision # => 0
401
+ */
402
+ static VALUE
403
+ BigDecimal_precision(VALUE self)
404
+ {
405
+ ENTER(1);
406
+
407
+ Real *p;
408
+ GUARD_OBJ(p, GetVpValue(self, 1));
409
+
410
+ /*
411
+ * The most significant digit is frac[0], and the least significant digit is frac[Prec-1].
412
+ * When the exponent is zero, the decimal point is located just before frac[0].
413
+ * When the exponent is negative, the decimal point moves to leftward.
414
+ * Conversely, when the exponent is positive, the decimal point moves to rightward.
415
+ *
416
+ * | frac[0] frac[1] frac[2] . frac[3] frac[4] ... frac[Prec-1]
417
+ * |------------------------> exponent == 3
418
+ */
419
+
420
+ ssize_t ex = p->exponent;
421
+ ssize_t precision;
422
+ if (ex < 0) {
423
+ precision = (-ex + 1) * BASE_FIG; /* 1 is for p->frac[0] */
424
+ ex = 0;
425
+ }
426
+ else if (p->Prec > 0) {
427
+ BDIGIT x = p->frac[0];
428
+ for (precision = 0; x > 0; x /= 10) {
429
+ ++precision;
430
+ }
431
+ }
432
+
433
+ if (ex > (ssize_t)p->Prec) {
434
+ precision += (ex - 1) * BASE_FIG;
435
+ }
436
+ else if (p->Prec > 0) {
437
+ ssize_t n = (ssize_t)p->Prec - 1;
438
+ while (n > 0 && p->frac[n] == 0) --n;
439
+
440
+ precision += n * BASE_FIG;
441
+
442
+ if (ex < (ssize_t)p->Prec) {
443
+ BDIGIT x = p->frac[n];
444
+ for (; x > 0 && x % 10 == 0; x /= 10) {
445
+ --precision;
446
+ }
447
+ }
448
+ }
449
+
450
+ return SSIZET2NUM(precision);
451
+ }
452
+
453
+ static VALUE
454
+ BigDecimal_n_significant_digits(VALUE self)
455
+ {
456
+ ENTER(1);
457
+
458
+ Real *p;
459
+ GUARD_OBJ(p, GetVpValue(self, 1));
460
+
461
+ ssize_t n = p->Prec;
462
+ while (n > 0 && p->frac[n-1] == 0) --n;
463
+ if (n <= 0) {
464
+ return INT2FIX(0);
465
+ }
466
+
467
+ int nlz, ntz;
468
+
469
+ BDIGIT x = p->frac[0];
470
+ for (nlz = BASE_FIG; x > 0; x /= 10) --nlz;
471
+
472
+ x = p->frac[n-1];
473
+ for (ntz = 0; x > 0 && x % 10 == 0; x /= 10) ++ntz;
474
+
475
+ ssize_t n_digits = BASE_FIG * n - nlz - ntz;
476
+ return SSIZET2NUM(n_digits);
477
+ }
478
+
375
479
  /*
376
480
  * call-seq: hash
377
481
  *
@@ -899,7 +1003,7 @@ BigDecimal_coerce(VALUE self, VALUE other)
899
1003
  Real *b;
900
1004
 
901
1005
  if (RB_TYPE_P(other, T_FLOAT)) {
902
- GUARD_OBJ(b, GetVpValueWithPrec(other, DBL_DIG+1, 1));
1006
+ GUARD_OBJ(b, GetVpValueWithPrec(other, DBLE_FIG, 1));
903
1007
  obj = rb_assoc_new(ToValue(b), self);
904
1008
  }
905
1009
  else {
@@ -957,7 +1061,7 @@ BigDecimal_add(VALUE self, VALUE r)
957
1061
 
958
1062
  GUARD_OBJ(a, GetVpValue(self, 1));
959
1063
  if (RB_TYPE_P(r, T_FLOAT)) {
960
- b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
1064
+ b = GetVpValueWithPrec(r, DBLE_FIG, 1);
961
1065
  }
962
1066
  else if (RB_TYPE_P(r, T_RATIONAL)) {
963
1067
  b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
@@ -1015,7 +1119,7 @@ BigDecimal_sub(VALUE self, VALUE r)
1015
1119
 
1016
1120
  GUARD_OBJ(a, GetVpValue(self,1));
1017
1121
  if (RB_TYPE_P(r, T_FLOAT)) {
1018
- b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
1122
+ b = GetVpValueWithPrec(r, DBLE_FIG, 1);
1019
1123
  }
1020
1124
  else if (RB_TYPE_P(r, T_RATIONAL)) {
1021
1125
  b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
@@ -1065,7 +1169,7 @@ BigDecimalCmp(VALUE self, VALUE r,char op)
1065
1169
  break;
1066
1170
 
1067
1171
  case T_FLOAT:
1068
- GUARD_OBJ(b, GetVpValueWithPrec(r, DBL_DIG+1, 0));
1172
+ GUARD_OBJ(b, GetVpValueWithPrec(r, DBLE_FIG, 0));
1069
1173
  break;
1070
1174
 
1071
1175
  case T_RATIONAL:
@@ -1278,7 +1382,7 @@ BigDecimal_mult(VALUE self, VALUE r)
1278
1382
 
1279
1383
  GUARD_OBJ(a, GetVpValue(self, 1));
1280
1384
  if (RB_TYPE_P(r, T_FLOAT)) {
1281
- b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
1385
+ b = GetVpValueWithPrec(r, DBLE_FIG, 1);
1282
1386
  }
1283
1387
  else if (RB_TYPE_P(r, T_RATIONAL)) {
1284
1388
  b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
@@ -1306,7 +1410,7 @@ BigDecimal_divide(Real **c, Real **res, Real **div, VALUE self, VALUE r)
1306
1410
 
1307
1411
  GUARD_OBJ(a, GetVpValue(self, 1));
1308
1412
  if (RB_TYPE_P(r, T_FLOAT)) {
1309
- b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
1413
+ b = GetVpValueWithPrec(r, DBLE_FIG, 1);
1310
1414
  }
1311
1415
  else if (RB_TYPE_P(r, T_RATIONAL)) {
1312
1416
  b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
@@ -1372,7 +1476,7 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod)
1372
1476
 
1373
1477
  GUARD_OBJ(a, GetVpValue(self, 1));
1374
1478
  if (RB_TYPE_P(r, T_FLOAT)) {
1375
- b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
1479
+ b = GetVpValueWithPrec(r, DBLE_FIG, 1);
1376
1480
  }
1377
1481
  else if (RB_TYPE_P(r, T_RATIONAL)) {
1378
1482
  b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
@@ -1473,7 +1577,7 @@ BigDecimal_divremain(VALUE self, VALUE r, Real **dv, Real **rv)
1473
1577
 
1474
1578
  GUARD_OBJ(a, GetVpValue(self, 1));
1475
1579
  if (RB_TYPE_P(r, T_FLOAT)) {
1476
- b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
1580
+ b = GetVpValueWithPrec(r, DBLE_FIG, 1);
1477
1581
  }
1478
1582
  else if (RB_TYPE_P(r, T_RATIONAL)) {
1479
1583
  b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
@@ -2685,7 +2789,7 @@ VpNewVarArg(int argc, VALUE *argv)
2685
2789
  VpDtoV(pv, d);
2686
2790
  return pv;
2687
2791
  }
2688
- if (mf > DBL_DIG+1) {
2792
+ if (mf > DBLE_FIG) {
2689
2793
  if (!exc) {
2690
2794
  return NULL;
2691
2795
  }
@@ -2980,7 +3084,7 @@ BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec)
2980
3084
  infinite = isinf(flo);
2981
3085
  nan = isnan(flo);
2982
3086
  if (!infinite && !nan) {
2983
- vx = GetVpValueWithPrec(x, DBL_DIG+1, 0);
3087
+ vx = GetVpValueWithPrec(x, DBLE_FIG, 0);
2984
3088
  }
2985
3089
  break;
2986
3090
 
@@ -3133,7 +3237,7 @@ get_vp_value:
3133
3237
  infinite = isinf(flo);
3134
3238
  nan = isnan(flo);
3135
3239
  if (!zero && !negative && !infinite && !nan) {
3136
- vx = GetVpValueWithPrec(x, DBL_DIG+1, 1);
3240
+ vx = GetVpValueWithPrec(x, DBLE_FIG, 1);
3137
3241
  }
3138
3242
  break;
3139
3243
 
@@ -3351,6 +3455,9 @@ get_vp_value:
3351
3455
  void
3352
3456
  Init_bigdecimal(void)
3353
3457
  {
3458
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
3459
+ rb_ext_ractor_safe(true);
3460
+ #endif
3354
3461
  VALUE arg;
3355
3462
 
3356
3463
  id_BigDecimal_exception_mode = rb_intern_const("BigDecimal.exception_mode");
@@ -3367,7 +3474,7 @@ Init_bigdecimal(void)
3367
3474
  rb_define_global_function("BigDecimal", f_BigDecimal, -1);
3368
3475
 
3369
3476
  /* Class methods */
3370
- rb_undef_method(CLASS_OF(rb_cBigDecimal), "allocate");
3477
+ rb_undef_alloc_func(rb_cBigDecimal);
3371
3478
  rb_undef_method(CLASS_OF(rb_cBigDecimal), "new");
3372
3479
  rb_define_singleton_method(rb_cBigDecimal, "interpret_loosely", BigDecimal_s_interpret_loosely, 1);
3373
3480
  rb_define_singleton_method(rb_cBigDecimal, "mode", BigDecimal_mode, -1);
@@ -3501,6 +3608,8 @@ Init_bigdecimal(void)
3501
3608
 
3502
3609
  /* instance methods */
3503
3610
  rb_define_method(rb_cBigDecimal, "precs", BigDecimal_prec, 0);
3611
+ rb_define_method(rb_cBigDecimal, "precision", BigDecimal_precision, 0);
3612
+ rb_define_method(rb_cBigDecimal, "n_significant_digits", BigDecimal_n_significant_digits, 0);
3504
3613
 
3505
3614
  rb_define_method(rb_cBigDecimal, "add", BigDecimal_add2, 2);
3506
3615
  rb_define_method(rb_cBigDecimal, "sub", BigDecimal_sub2, 2);
@@ -3617,6 +3726,9 @@ static void VpFormatSt(char *psz, size_t fFmt);
3617
3726
  static int VpRdup(Real *m, size_t ind_m);
3618
3727
 
3619
3728
  #ifdef BIGDECIMAL_DEBUG
3729
+ # ifdef HAVE_RB_EXT_RACTOR_SAFE
3730
+ # error Need to make rewiting gnAlloc atomic
3731
+ # endif
3620
3732
  static int gnAlloc = 0; /* Memory allocation counter */
3621
3733
  #endif /* BIGDECIMAL_DEBUG */
3622
3734
 
@@ -4023,7 +4135,7 @@ VpNumOfChars(Real *vp,const char *pszFmt)
4023
4135
  * by one BDIGIT word in the computer used.
4024
4136
  *
4025
4137
  * [Returns]
4026
- * 1+DBL_DIG ... OK
4138
+ * DBLE_FIG ... OK
4027
4139
  */
4028
4140
  VP_EXPORT size_t
4029
4141
  VpInit(BDIGIT BaseVal)
@@ -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
@@ -42,6 +42,8 @@ have_func("rb_complex_imag", "ruby.h")
42
42
  have_func("rb_array_const_ptr", "ruby.h")
43
43
  have_func("rb_sym2str", "ruby.h")
44
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")
45
47
 
46
48
  if File.file?(File.expand_path('../lib/bigdecimal.rb', __FILE__))
47
49
  bigdecimal_rb = "$(srcdir)/lib/bigdecimal.rb"
@@ -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
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: 2.0.2
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenta Murata
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-12-15 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
@@ -109,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  requirements: []
112
- rubygems_version: 3.1.4
112
+ rubygems_version: 3.2.2
113
113
  signing_key:
114
114
  specification_version: 4
115
115
  summary: Arbitrary-precision decimal floating-point number library.