bigdecimal 3.1.7 → 3.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: 8bd666f800ebaf8bf81b991c2220587d621521c6d02548680bfbb4ff55b245b7
4
- data.tar.gz: 15be279642ac5dd98f2470df7a46fc288992b450a1d5f1629d52c701377d191d
3
+ metadata.gz: d4fdad45c0e9519d352fa25d4134af80ce6897c8196bcb3bf0e25d6ebcea8918
4
+ data.tar.gz: ed56f36c2e5fd8cea29b0de49ac2c25edf186de643d69aff660677ada7a79ae8
5
5
  SHA512:
6
- metadata.gz: 123b9d9b3b3a5d9ab3664b2887cee0d846f8b9a1e87d590e06751a844759e31e4286b28ad578e6fb14b4975890ed7179cbfbc660196b6cb3c23f9cb8e7eddb16
7
- data.tar.gz: 6ad102cec32ddceb2c6c19fdb4821bda9fe9c3c0e07b4b3d3eb8b98ce9b3ec60d887d1446efecce0d86675b02d5138a11028ea1bd2cd494ddc3a836082e9ba7a
6
+ metadata.gz: 2481253ce262ad322882ca3c3ae5c14eec4b4cc599c34c4aac0e71f3161cece17adce5b506fc94548018ab9605c411e1746d40bdc9f086ef3dfd085197ce7d15
7
+ data.tar.gz: cb3ee7815dd3d4f63271ffb09c09ff485dd9603b6fc5cb639416cf1f7c20df576aac5e53c891245bbc0a03789b4f2dcd514cf7e48c186f05f58600a799a5ed6e
data/bigdecimal.gemspec CHANGED
@@ -52,4 +52,6 @@ Gem::Specification.new do |s|
52
52
  end
53
53
 
54
54
  s.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
55
+
56
+ s.metadata["changelog_uri"] = s.homepage + "/blob/master/CHANGES.md"
55
57
  end
@@ -31,7 +31,7 @@
31
31
  #include "bits.h"
32
32
  #include "static_assert.h"
33
33
 
34
- #define BIGDECIMAL_VERSION "3.1.7"
34
+ #define BIGDECIMAL_VERSION "3.2.0"
35
35
 
36
36
  /* #define ENABLE_NUMERIC_STRING */
37
37
 
@@ -1485,7 +1485,8 @@ BigDecimal_add(VALUE self, VALUE r)
1485
1485
  return VpCheckGetValue(c);
1486
1486
  }
1487
1487
 
1488
- /* call-seq:
1488
+ /*
1489
+ * call-seq:
1489
1490
  * self - value -> bigdecimal
1490
1491
  *
1491
1492
  * Returns the \BigDecimal difference of +self+ and +value+:
@@ -1780,6 +1781,17 @@ BigDecimal_neg(VALUE self)
1780
1781
  return VpCheckGetValue(c);
1781
1782
  }
1782
1783
 
1784
+ /*
1785
+ * call-seq:
1786
+ * a * b -> bigdecimal
1787
+ *
1788
+ * Multiply by the specified value.
1789
+ *
1790
+ * The result precision will be the precision of the sum of each precision.
1791
+ *
1792
+ * See BigDecimal#mult.
1793
+ */
1794
+
1783
1795
  static VALUE
1784
1796
  BigDecimal_mult(VALUE self, VALUE r)
1785
1797
  {
@@ -1807,55 +1819,6 @@ BigDecimal_mult(VALUE self, VALUE r)
1807
1819
  return VpCheckGetValue(c);
1808
1820
  }
1809
1821
 
1810
- static VALUE
1811
- BigDecimal_divide(VALUE self, VALUE r, Real **c, Real **res, Real **div)
1812
- /* For c = self.div(r): with round operation */
1813
- {
1814
- ENTER(5);
1815
- Real *a, *b;
1816
- ssize_t a_prec, b_prec;
1817
- size_t mx;
1818
-
1819
- TypedData_Get_Struct(self, Real, &BigDecimal_data_type, a);
1820
- SAVE(a);
1821
-
1822
- VALUE rr = r;
1823
- if (is_kind_of_BigDecimal(rr)) {
1824
- /* do nothing */
1825
- }
1826
- else if (RB_INTEGER_TYPE_P(r)) {
1827
- rr = rb_inum_convert_to_BigDecimal(r, 0, true);
1828
- }
1829
- else if (RB_TYPE_P(r, T_FLOAT)) {
1830
- rr = rb_float_convert_to_BigDecimal(r, 0, true);
1831
- }
1832
- else if (RB_TYPE_P(r, T_RATIONAL)) {
1833
- rr = rb_rational_convert_to_BigDecimal(r, a->Prec*BASE_FIG, true);
1834
- }
1835
-
1836
- if (!is_kind_of_BigDecimal(rr)) {
1837
- return DoSomeOne(self, r, '/');
1838
- }
1839
-
1840
- TypedData_Get_Struct(rr, Real, &BigDecimal_data_type, b);
1841
- SAVE(b);
1842
- *div = b;
1843
-
1844
- BigDecimal_count_precision_and_scale(self, &a_prec, NULL);
1845
- BigDecimal_count_precision_and_scale(rr, &b_prec, NULL);
1846
- mx = (a_prec > b_prec) ? a_prec : b_prec;
1847
- mx *= 2;
1848
-
1849
- if (2*BIGDECIMAL_DOUBLE_FIGURES > mx)
1850
- mx = 2*BIGDECIMAL_DOUBLE_FIGURES;
1851
-
1852
- GUARD_OBJ((*c), NewZeroWrapNolimit(1, mx + 2*BASE_FIG));
1853
- GUARD_OBJ((*res), NewZeroWrapNolimit(1, (mx + 1)*2 + 2*BASE_FIG));
1854
- VpDivd(*c, *res, a, b);
1855
-
1856
- return Qnil;
1857
- }
1858
-
1859
1822
  static VALUE BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod);
1860
1823
 
1861
1824
  /* call-seq:
@@ -1873,20 +1836,15 @@ static VALUE
1873
1836
  BigDecimal_div(VALUE self, VALUE r)
1874
1837
  /* For c = self/r: with round operation */
1875
1838
  {
1876
- ENTER(5);
1877
- Real *c=NULL, *res=NULL, *div = NULL;
1878
- r = BigDecimal_divide(self, r, &c, &res, &div);
1879
- if (!NIL_P(r)) return r; /* coerced by other */
1880
- SAVE(c); SAVE(res); SAVE(div);
1881
- /* a/b = c + r/b */
1882
- /* c xxxxx
1883
- r 00000yyyyy ==> (y/b)*BASE >= HALF_BASE
1884
- */
1885
- /* Round */
1886
- if (VpHasVal(div)) { /* frac[0] must be zero for NaN,INF,Zero */
1887
- VpInternalRound(c, 0, c->frac[c->Prec-1], (DECDIG)(VpBaseVal() * (DECDIG_DBL)res->frac[0] / div->frac[0]));
1839
+ if (
1840
+ !is_kind_of_BigDecimal(r) &&
1841
+ !RB_INTEGER_TYPE_P(r) &&
1842
+ !RB_TYPE_P(r, T_FLOAT) &&
1843
+ !RB_TYPE_P(r, T_RATIONAL)
1844
+ ) {
1845
+ return DoSomeOne(self, r, '/');
1888
1846
  }
1889
- return VpCheckGetValue(c);
1847
+ return BigDecimal_div2(self, r, INT2FIX(0));
1890
1848
  }
1891
1849
 
1892
1850
  static VALUE BigDecimal_round(int argc, VALUE *argv, VALUE self);
@@ -2042,8 +2000,8 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod)
2042
2000
  }
2043
2001
 
2044
2002
  /* call-seq:
2045
- * a % b
2046
- * a.modulo(b)
2003
+ * a % b
2004
+ * a.modulo(b)
2047
2005
  *
2048
2006
  * Returns the modulus from dividing by b.
2049
2007
  *
@@ -2116,7 +2074,7 @@ BigDecimal_divremain(VALUE self, VALUE r, Real **dv, Real **rv)
2116
2074
  }
2117
2075
 
2118
2076
  /* call-seq:
2119
- * remainder(value)
2077
+ * remainder(value)
2120
2078
  *
2121
2079
  * Returns the remainder from dividing by the value.
2122
2080
  *
@@ -2133,7 +2091,7 @@ BigDecimal_remainder(VALUE self, VALUE r) /* remainder */
2133
2091
  }
2134
2092
 
2135
2093
  /* call-seq:
2136
- * divmod(value)
2094
+ * divmod(value)
2137
2095
  *
2138
2096
  * Divides by the specified value, and returns the quotient and modulus
2139
2097
  * as BigDecimal numbers. The quotient is rounded towards negative infinity.
@@ -2176,6 +2134,9 @@ BigDecimal_div2(VALUE self, VALUE b, VALUE n)
2176
2134
  {
2177
2135
  ENTER(5);
2178
2136
  SIGNED_VALUE ix;
2137
+ Real *res = NULL;
2138
+ Real *av = NULL, *bv = NULL, *cv = NULL;
2139
+ size_t mx, pl;
2179
2140
 
2180
2141
  if (NIL_P(n)) { /* div in Float sense */
2181
2142
  Real *div = NULL;
@@ -2188,33 +2149,48 @@ BigDecimal_div2(VALUE self, VALUE b, VALUE n)
2188
2149
 
2189
2150
  /* div in BigDecimal sense */
2190
2151
  ix = check_int_precision(n);
2191
- if (ix == 0) {
2192
- return BigDecimal_div(self, b);
2193
- }
2194
- else {
2195
- Real *res = NULL;
2196
- Real *av = NULL, *bv = NULL, *cv = NULL;
2197
- size_t mx = ix + VpBaseFig()*2;
2198
- size_t b_prec = ix;
2199
- size_t pl = VpSetPrecLimit(0);
2200
-
2201
- GUARD_OBJ(cv, NewZeroWrapLimited(1, mx + VpBaseFig()));
2202
- GUARD_OBJ(av, GetVpValue(self, 1));
2152
+
2153
+ pl = VpSetPrecLimit(0);
2154
+
2155
+ GUARD_OBJ(av, GetVpValue(self, 1));
2156
+ if (RB_FLOAT_TYPE_P(b) && ix > BIGDECIMAL_DOUBLE_FIGURES) {
2203
2157
  /* TODO: I want to refactor this precision control for a float value later
2204
2158
  * by introducing an implicit conversion function instead of
2205
2159
  * GetVpValueWithPrec. */
2206
- if (RB_FLOAT_TYPE_P(b) && b_prec > BIGDECIMAL_DOUBLE_FIGURES) {
2207
- b_prec = BIGDECIMAL_DOUBLE_FIGURES;
2208
- }
2209
- GUARD_OBJ(bv, GetVpValueWithPrec(b, b_prec, 1));
2210
- mx = av->Prec + bv->Prec + 2;
2211
- if (mx <= cv->MaxPrec) mx = cv->MaxPrec + 1;
2212
- GUARD_OBJ(res, NewZeroWrapNolimit(1, (mx * 2 + 2)*VpBaseFig()));
2213
- VpDivd(cv, res, av, bv);
2214
- VpSetPrecLimit(pl);
2215
- VpLeftRound(cv, VpGetRoundMode(), ix);
2216
- return VpCheckGetValue(cv);
2160
+ GUARD_OBJ(bv, GetVpValueWithPrec(b, BIGDECIMAL_DOUBLE_FIGURES, 1));
2217
2161
  }
2162
+ else {
2163
+ GUARD_OBJ(bv, GetVpValueWithPrec(b, ix, 1));
2164
+ }
2165
+
2166
+ if (ix == 0) {
2167
+ ssize_t a_prec, b_prec;
2168
+ BigDecimal_count_precision_and_scale(av->obj, &a_prec, NULL);
2169
+ BigDecimal_count_precision_and_scale(bv->obj, &b_prec, NULL);
2170
+ ix = ((a_prec > b_prec) ? a_prec : b_prec) + BIGDECIMAL_DOUBLE_FIGURES;
2171
+ if (2 * BIGDECIMAL_DOUBLE_FIGURES > ix)
2172
+ ix = 2 * BIGDECIMAL_DOUBLE_FIGURES;
2173
+ }
2174
+
2175
+ // VpDivd needs 2 extra DECDIGs. One more is needed for rounding.
2176
+ GUARD_OBJ(cv, NewZeroWrapLimited(1, ix + 3 * VpBaseFig()));
2177
+
2178
+ mx = bv->Prec + cv->MaxPrec - 1;
2179
+ if (mx <= av->Prec) mx = av->Prec + 1;
2180
+ GUARD_OBJ(res, NewZeroWrapNolimit(1, mx * VpBaseFig()));
2181
+ VpDivd(cv, res, av, bv);
2182
+ VpSetPrecLimit(pl);
2183
+ if (!VpIsZero(res)) {
2184
+ // Remainder value affects rounding result.
2185
+ // ROUND_UP cv = 0.1e0 with ix=10 will be:
2186
+ // 0.1e0 if remainder == 0
2187
+ // 0.1000000001e0 if remainder != 0
2188
+ size_t idx = roomof(ix, BASE_FIG);
2189
+ while (cv->Prec <= idx) cv->frac[cv->Prec++] = 0;
2190
+ if (cv->frac[idx] == 0 || cv->frac[idx] == HALF_BASE) cv->frac[idx]++;
2191
+ }
2192
+ VpLeftRound(cv, VpGetRoundMode(), ix);
2193
+ return VpCheckGetValue(cv);
2218
2194
  }
2219
2195
 
2220
2196
  /*
@@ -2305,7 +2281,7 @@ BigDecimal_add2(VALUE self, VALUE b, VALUE n)
2305
2281
  }
2306
2282
 
2307
2283
  /* call-seq:
2308
- * sub(value, digits) -> bigdecimal
2284
+ * sub(value, digits) -> bigdecimal
2309
2285
  *
2310
2286
  * Subtract the specified value.
2311
2287
  *
@@ -2404,7 +2380,7 @@ BigDecimal_abs(VALUE self)
2404
2380
  }
2405
2381
 
2406
2382
  /* call-seq:
2407
- * sqrt(n)
2383
+ * sqrt(n)
2408
2384
  *
2409
2385
  * Returns the square root of the value.
2410
2386
  *
@@ -2445,10 +2421,10 @@ BigDecimal_fix(VALUE self)
2445
2421
  }
2446
2422
 
2447
2423
  /* call-seq:
2448
- * round(n, mode)
2424
+ * round(n, mode)
2449
2425
  *
2450
2426
  * Round to the nearest integer (by default), returning the result as a
2451
- * BigDecimal if n is specified, or as an Integer if it isn't.
2427
+ * BigDecimal if n is specified and positive, or as an Integer if it isn't.
2452
2428
  *
2453
2429
  * BigDecimal('3.14159').round #=> 3
2454
2430
  * BigDecimal('8.7').round #=> 9
@@ -2456,6 +2432,7 @@ BigDecimal_fix(VALUE self)
2456
2432
  *
2457
2433
  * BigDecimal('3.14159').round(2).class.name #=> "BigDecimal"
2458
2434
  * BigDecimal('3.14159').round.class.name #=> "Integer"
2435
+ * BigDecimal('3.14159').round(0).class.name #=> "Integer"
2459
2436
  *
2460
2437
  * If n is specified and positive, the fractional part of the result has no
2461
2438
  * more than that many digits.
@@ -2522,7 +2499,7 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
2522
2499
  }
2523
2500
 
2524
2501
  /* call-seq:
2525
- * truncate(n)
2502
+ * truncate(n)
2526
2503
  *
2527
2504
  * Truncate to the nearest integer (by default), returning the result as a
2528
2505
  * BigDecimal.
@@ -2584,7 +2561,7 @@ BigDecimal_frac(VALUE self)
2584
2561
  }
2585
2562
 
2586
2563
  /* call-seq:
2587
- * floor(n)
2564
+ * floor(n)
2588
2565
  *
2589
2566
  * Return the largest integer less than or equal to the value, as a BigDecimal.
2590
2567
  *
@@ -2631,7 +2608,7 @@ BigDecimal_floor(int argc, VALUE *argv, VALUE self)
2631
2608
  }
2632
2609
 
2633
2610
  /* call-seq:
2634
- * ceil(n)
2611
+ * ceil(n)
2635
2612
  *
2636
2613
  * Return the smallest integer greater than or equal to the value, as a BigDecimal.
2637
2614
  *
@@ -2674,7 +2651,7 @@ BigDecimal_ceil(int argc, VALUE *argv, VALUE self)
2674
2651
  }
2675
2652
 
2676
2653
  /* call-seq:
2677
- * to_s(s)
2654
+ * to_s(s)
2678
2655
  *
2679
2656
  * Converts the value to a string.
2680
2657
  *
@@ -2984,8 +2961,8 @@ bigdecimal_power_by_bigdecimal(Real const* x, Real const* exp, ssize_t const n)
2984
2961
  }
2985
2962
 
2986
2963
  /* call-seq:
2987
- * power(n)
2988
- * power(n, prec)
2964
+ * power(n)
2965
+ * power(n, prec)
2989
2966
  *
2990
2967
  * Returns the value raised to the power of n.
2991
2968
  *
@@ -3257,10 +3234,11 @@ BigDecimal_initialize_copy(VALUE self, VALUE other)
3257
3234
  return self;
3258
3235
  }
3259
3236
 
3237
+ /* :nodoc: */
3260
3238
  static VALUE
3261
3239
  BigDecimal_clone(VALUE self)
3262
3240
  {
3263
- return self;
3241
+ return self;
3264
3242
  }
3265
3243
 
3266
3244
  #ifdef HAVE_RB_OPTS_EXCEPTION_P
@@ -3758,6 +3736,12 @@ f_BigDecimal(int argc, VALUE *argv, VALUE self)
3758
3736
  return rb_convert_to_BigDecimal(val, digs, exception);
3759
3737
  }
3760
3738
 
3739
+ /* call-seq:
3740
+ * BigDecimal.interpret_loosely(string) -> bigdecimal
3741
+ *
3742
+ * Returns the +BigDecimal+ converted loosely from +string+.
3743
+ */
3744
+
3761
3745
  static VALUE
3762
3746
  BigDecimal_s_interpret_loosely(VALUE klass, VALUE str)
3763
3747
  {
@@ -3769,8 +3753,9 @@ BigDecimal_s_interpret_loosely(VALUE klass, VALUE str)
3769
3753
  return VpCheckGetValue(vp);
3770
3754
  }
3771
3755
 
3772
- /* call-seq:
3773
- * BigDecimal.limit(digits)
3756
+ /*
3757
+ * call-seq:
3758
+ * BigDecimal.limit(digits)
3774
3759
  *
3775
3760
  * Limit the number of significant digits in newly created BigDecimal
3776
3761
  * numbers to the specified value. Rounding is performed as necessary,
@@ -3904,7 +3889,7 @@ BigDecimal_save_limit(VALUE self)
3904
3889
  }
3905
3890
 
3906
3891
  /* call-seq:
3907
- * BigMath.exp(decimal, numeric) -> BigDecimal
3892
+ * BigMath.exp(decimal, numeric) -> BigDecimal
3908
3893
  *
3909
3894
  * Computes the value of e (the base of natural logarithms) raised to the
3910
3895
  * power of +decimal+, to the specified number of digits of precision.
@@ -4035,7 +4020,7 @@ BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec)
4035
4020
  }
4036
4021
 
4037
4022
  /* call-seq:
4038
- * BigMath.log(decimal, numeric) -> BigDecimal
4023
+ * BigMath.log(decimal, numeric) -> BigDecimal
4039
4024
  *
4040
4025
  * Computes the natural logarithm of +decimal+ to the specified number of
4041
4026
  * digits of precision, +numeric+.
@@ -4238,6 +4223,17 @@ BigDecimal_negative_zero(void)
4238
4223
  return BIGDECIMAL_NEGATIVE_ZERO;
4239
4224
  }
4240
4225
 
4226
+ static inline VALUE
4227
+ BigDecimal_literal(const char *str)
4228
+ {
4229
+ VALUE arg = rb_str_new_cstr(str);
4230
+ VALUE val = f_BigDecimal(1, &arg, rb_cBigDecimal);
4231
+ rb_gc_register_mark_object(val);
4232
+ return val;
4233
+ }
4234
+
4235
+ #define BIGDECIMAL_LITERAL(var, val) (BIGDECIMAL_ ## var = BigDecimal_literal(#val))
4236
+
4241
4237
  /* Document-class: BigDecimal
4242
4238
  * BigDecimal provides arbitrary-precision floating point decimal arithmetic.
4243
4239
  *
@@ -4394,7 +4390,6 @@ Init_bigdecimal(void)
4394
4390
  #ifdef HAVE_RB_EXT_RACTOR_SAFE
4395
4391
  rb_ext_ractor_safe(true);
4396
4392
  #endif
4397
- VALUE arg;
4398
4393
 
4399
4394
  id_BigDecimal_exception_mode = rb_intern_const("BigDecimal.exception_mode");
4400
4395
  id_BigDecimal_rounding_mode = rb_intern_const("BigDecimal.rounding_mode");
@@ -4532,33 +4527,19 @@ Init_bigdecimal(void)
4532
4527
  rb_define_const(rb_cBigDecimal, "SIGN_NEGATIVE_INFINITE", INT2FIX(VP_SIGN_NEGATIVE_INFINITE));
4533
4528
 
4534
4529
  /* Positive zero value. */
4535
- arg = rb_str_new2("+0");
4536
- BIGDECIMAL_POSITIVE_ZERO = f_BigDecimal(1, &arg, rb_cBigDecimal);
4537
- rb_gc_register_mark_object(BIGDECIMAL_POSITIVE_ZERO);
4530
+ BIGDECIMAL_LITERAL(POSITIVE_ZERO, +0);
4538
4531
 
4539
4532
  /* Negative zero value. */
4540
- arg = rb_str_new2("-0");
4541
- BIGDECIMAL_NEGATIVE_ZERO = f_BigDecimal(1, &arg, rb_cBigDecimal);
4542
- rb_gc_register_mark_object(BIGDECIMAL_NEGATIVE_ZERO);
4533
+ BIGDECIMAL_LITERAL(NEGATIVE_ZERO, -0);
4543
4534
 
4544
- /* Positive infinity value. */
4545
- arg = rb_str_new2("+Infinity");
4546
- BIGDECIMAL_POSITIVE_INFINITY = f_BigDecimal(1, &arg, rb_cBigDecimal);
4547
- rb_gc_register_mark_object(BIGDECIMAL_POSITIVE_INFINITY);
4535
+ /* Positive infinity[rdoc-ref:BigDecimal@Infinity] value. */
4536
+ rb_define_const(rb_cBigDecimal, "INFINITY", BIGDECIMAL_LITERAL(POSITIVE_INFINITY, +Infinity));
4548
4537
 
4549
4538
  /* Negative infinity value. */
4550
- arg = rb_str_new2("-Infinity");
4551
- BIGDECIMAL_NEGATIVE_INFINITY = f_BigDecimal(1, &arg, rb_cBigDecimal);
4552
- rb_gc_register_mark_object(BIGDECIMAL_NEGATIVE_INFINITY);
4553
-
4554
- /* 'Not a Number' value. */
4555
- arg = rb_str_new2("NaN");
4556
- BIGDECIMAL_NAN = f_BigDecimal(1, &arg, rb_cBigDecimal);
4557
- rb_gc_register_mark_object(BIGDECIMAL_NAN);
4539
+ BIGDECIMAL_LITERAL(NEGATIVE_INFINITY, -Infinity);
4558
4540
 
4559
- /* Special value constants */
4560
- rb_define_const(rb_cBigDecimal, "INFINITY", BIGDECIMAL_POSITIVE_INFINITY);
4561
- rb_define_const(rb_cBigDecimal, "NAN", BIGDECIMAL_NAN);
4541
+ /* '{Not a Number}[rdoc-ref:BigDecimal@Not+a+Number]' value. */
4542
+ rb_define_const(rb_cBigDecimal, "NAN", BIGDECIMAL_LITERAL(NAN, NaN));
4562
4543
 
4563
4544
  /* instance methods */
4564
4545
  rb_define_method(rb_cBigDecimal, "precs", BigDecimal_prec, 0);
@@ -5203,6 +5184,48 @@ bigdecimal_parse_special_string(const char *str)
5203
5184
  return NULL;
5204
5185
  }
5205
5186
 
5187
+ struct VpCtoV_args {
5188
+ Real *a;
5189
+ const char *int_chr;
5190
+ size_t ni;
5191
+ const char *frac;
5192
+ size_t nf;
5193
+ const char *exp_chr;
5194
+ size_t ne;
5195
+ };
5196
+
5197
+ static VALUE
5198
+ call_VpCtoV(VALUE arg)
5199
+ {
5200
+ struct VpCtoV_args *x = (struct VpCtoV_args *)arg;
5201
+ return (VALUE)VpCtoV(x->a, x->int_chr, x->ni, x->frac, x->nf, x->exp_chr, x->ne);
5202
+ }
5203
+
5204
+ static int
5205
+ protected_VpCtoV(Real *a, const char *int_chr, size_t ni, const char *frac, size_t nf, const char *exp_chr, size_t ne, int free_on_error)
5206
+ {
5207
+ struct VpCtoV_args args;
5208
+ int state = 0;
5209
+
5210
+ args.a = a;
5211
+ args.int_chr = int_chr;
5212
+ args.ni = ni;
5213
+ args.frac = frac;
5214
+ args.nf = nf;
5215
+ args.exp_chr = exp_chr;
5216
+ args.ne = ne;
5217
+
5218
+ VALUE result = rb_protect(call_VpCtoV, (VALUE)&args, &state);
5219
+ if (state) {
5220
+ if (free_on_error) {
5221
+ rbd_free_struct(a);
5222
+ }
5223
+ rb_jump_tag(state);
5224
+ }
5225
+
5226
+ return (int)result;
5227
+ }
5228
+
5206
5229
  /*
5207
5230
  * Allocates variable.
5208
5231
  * [Input]
@@ -5220,7 +5243,7 @@ VP_EXPORT Real *
5220
5243
  VpAlloc(size_t mx, const char *szVal, int strict_p, int exc)
5221
5244
  {
5222
5245
  const char *orig_szVal = szVal;
5223
- size_t i, j, ni, ipf, nf, ipe, ne, dot_seen, exp_seen, nalloc;
5246
+ size_t i, j, ni, ipf, nf, ipe, ne, exp_seen, nalloc;
5224
5247
  size_t len;
5225
5248
  char v, *psz;
5226
5249
  int sign=1;
@@ -5306,13 +5329,11 @@ VpAlloc(size_t mx, const char *szVal, int strict_p, int exc)
5306
5329
  ne = 0; /* number of digits in the exponential part */
5307
5330
  ipf = 0; /* index of the beginning of the fractional part */
5308
5331
  ipe = 0; /* index of the beginning of the exponential part */
5309
- dot_seen = 0;
5310
5332
  exp_seen = 0;
5311
5333
 
5312
5334
  if (v != '\0') {
5313
5335
  /* Scanning fractional part */
5314
5336
  if ((psz[i] = szVal[j]) == '.') {
5315
- dot_seen = 1;
5316
5337
  ++i;
5317
5338
  ++j;
5318
5339
  ipf = i;
@@ -5328,9 +5349,6 @@ VpAlloc(size_t mx, const char *szVal, int strict_p, int exc)
5328
5349
  }
5329
5350
  if (!strict_p) {
5330
5351
  v = psz[i] = '\0';
5331
- if (nf == 0) {
5332
- dot_seen = 0;
5333
- }
5334
5352
  break;
5335
5353
  }
5336
5354
  goto invalid_value;
@@ -5401,7 +5419,7 @@ VpAlloc(size_t mx, const char *szVal, int strict_p, int exc)
5401
5419
 
5402
5420
  psz[i] = '\0';
5403
5421
 
5404
- if (strict_p && (((ni == 0 || dot_seen) && nf == 0) || (exp_seen && ne == 0))) {
5422
+ if (strict_p && ((ni == 0 && nf == 0) || (exp_seen && ne == 0))) {
5405
5423
  VALUE str;
5406
5424
  invalid_value:
5407
5425
  if (!strict_p) {
@@ -5422,7 +5440,7 @@ VpAlloc(size_t mx, const char *szVal, int strict_p, int exc)
5422
5440
  vp = rbd_allocate_struct(len);
5423
5441
  vp->MaxPrec = len; /* set max precision */
5424
5442
  VpSetZero(vp, sign);
5425
- VpCtoV(vp, psz, ni, psz + ipf, nf, psz + ipe, ne);
5443
+ protected_VpCtoV(vp, psz, ni, psz + ipf, nf, psz + ipe, ne, true);
5426
5444
  rb_str_resize(buf, 0);
5427
5445
  return vp;
5428
5446
  }
@@ -6112,7 +6130,7 @@ VpDivd(Real *c, Real *r, Real *a, Real *b)
6112
6130
  word_c = c->MaxPrec;
6113
6131
  word_r = r->MaxPrec;
6114
6132
 
6115
- if (word_a >= word_r) goto space_error;
6133
+ if (word_a >= word_r || word_b + word_c - 2 >= word_r) goto space_error;
6116
6134
 
6117
6135
  ind_r = 1;
6118
6136
  r->frac[0] = 0;
@@ -24,15 +24,17 @@ have_header("math.h")
24
24
  have_header("stdbool.h")
25
25
  have_header("stdlib.h")
26
26
 
27
- have_header("x86intrin.h")
28
- have_func("_lzcnt_u32", "x86intrin.h")
29
- have_func("_lzcnt_u64", "x86intrin.h")
30
-
31
- have_header("intrin.h")
32
- have_func("__lzcnt", "intrin.h")
33
- have_func("__lzcnt64", "intrin.h")
34
- have_func("_BitScanReverse", "intrin.h")
35
- have_func("_BitScanReverse64", "intrin.h")
27
+ if have_header("x86intrin.h")
28
+ have_func("_lzcnt_u32", "x86intrin.h")
29
+ have_func("_lzcnt_u64", "x86intrin.h")
30
+ end
31
+
32
+ if have_header("intrin.h")
33
+ have_func("__lzcnt", "intrin.h")
34
+ have_func("__lzcnt64", "intrin.h")
35
+ have_func("_BitScanReverse", "intrin.h")
36
+ have_func("_BitScanReverse64", "intrin.h")
37
+ end
36
38
 
37
39
  have_func("labs", "stdlib.h")
38
40
  have_func("llabs", "stdlib.h")
@@ -15,7 +15,8 @@
15
15
  _Pragma("GCC diagnostic push") \
16
16
  _Pragma("GCC diagnostic ignored \"-Wattributes\"") \
17
17
  __attribute__((__no_sanitize__(x))) y; \
18
- _Pragma("GCC diagnostic pop")
18
+ _Pragma("GCC diagnostic pop") \
19
+ y
19
20
  #endif
20
21
 
21
22
  #undef strtod
@@ -7,13 +7,12 @@ require 'bigdecimal'
7
7
  # sqrt(x, prec)
8
8
  # sin (x, prec)
9
9
  # cos (x, prec)
10
- # atan(x, prec) Note: |x|<1, x=0.9999 may not converge.
10
+ # atan(x, prec)
11
11
  # PI (prec)
12
12
  # E (prec) == exp(1.0,prec)
13
13
  #
14
14
  # where:
15
15
  # x ... BigDecimal number to be computed.
16
- # |x| must be small enough to get convergence.
17
16
  # prec ... Number of digits to be obtained.
18
17
  #++
19
18
  #
@@ -155,7 +155,7 @@ class Complex < Numeric
155
155
  # See also Kernel.BigDecimal.
156
156
  #
157
157
  def to_d(*args)
158
- BigDecimal(self) unless self.imag.zero? # to raise eerror
158
+ BigDecimal(self) unless self.imag.zero? # to raise error
159
159
 
160
160
  if args.length == 0
161
161
  case self.real
metadata CHANGED
@@ -1,15 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bigdecimal
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.7
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenta Murata
8
8
  - Zachary Scott
9
9
  - Shigeo Kobayashi
10
+ autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2024-03-14 00:00:00.000000000 Z
13
+ date: 2025-05-29 00:00:00.000000000 Z
13
14
  dependencies: []
14
15
  description: This library provides arbitrary-precision decimal floating-point number
15
16
  class.
@@ -44,7 +45,9 @@ homepage: https://github.com/ruby/bigdecimal
44
45
  licenses:
45
46
  - Ruby
46
47
  - BSD-2-Clause
47
- metadata: {}
48
+ metadata:
49
+ changelog_uri: https://github.com/ruby/bigdecimal/blob/master/CHANGES.md
50
+ post_install_message:
48
51
  rdoc_options: []
49
52
  require_paths:
50
53
  - lib
@@ -59,7 +62,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
59
62
  - !ruby/object:Gem::Version
60
63
  version: '0'
61
64
  requirements: []
62
- rubygems_version: 3.6.0.dev
65
+ rubygems_version: 3.5.10
66
+ signing_key:
63
67
  specification_version: 4
64
68
  summary: Arbitrary-precision decimal floating-point number library.
65
69
  test_files: []