bigdecimal 3.1.7 → 3.2.2

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: 8737ecb678e63a8a9e0aefe2d0ea606a523915d08b66b69704967749e15e53bf
4
+ data.tar.gz: 0dec9bb1cf41f347efdc60b918bab5f14264e6fc082011870dbc62391fde1270
5
5
  SHA512:
6
- metadata.gz: 123b9d9b3b3a5d9ab3664b2887cee0d846f8b9a1e87d590e06751a844759e31e4286b28ad578e6fb14b4975890ed7179cbfbc660196b6cb3c23f9cb8e7eddb16
7
- data.tar.gz: 6ad102cec32ddceb2c6c19fdb4821bda9fe9c3c0e07b4b3d3eb8b98ce9b3ec60d887d1446efecce0d86675b02d5138a11028ea1bd2cd494ddc3a836082e9ba7a
6
+ metadata.gz: ddacbb0df3b6976bc560fab41363de45e4776c6e56d884a2c00a71015b838ff83d2a26b87e4af63d3e60fff27f6e90638f7cd6b363c62d06c78ac4c8250d6d5a
7
+ data.tar.gz: bc4ee4ace918f04364f882b69acb9c60bca9abc2405f426bbaa5831af21a9508c02c73c1f7302a3f25d387b7518d42095bc7bcbb817151e84ca2b9b0ce6889b5
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.2"
35
35
 
36
36
  /* #define ENABLE_NUMERIC_STRING */
37
37
 
@@ -513,15 +513,10 @@ BigDecimal_prec(VALUE self)
513
513
  }
514
514
 
515
515
  static void
516
- BigDecimal_count_precision_and_scale(VALUE self, ssize_t *out_precision, ssize_t *out_scale)
516
+ VpCountPrecisionAndScale(Real *p, ssize_t *out_precision, ssize_t *out_scale)
517
517
  {
518
- ENTER(1);
519
-
520
518
  if (out_precision == NULL && out_scale == NULL)
521
519
  return;
522
-
523
- Real *p;
524
- GUARD_OBJ(p, GetVpValue(self, 1));
525
520
  if (VpIsZero(p) || !VpIsDef(p)) {
526
521
  zero:
527
522
  if (out_precision) *out_precision = 0;
@@ -625,6 +620,15 @@ BigDecimal_count_precision_and_scale(VALUE self, ssize_t *out_precision, ssize_t
625
620
  }
626
621
  }
627
622
 
623
+ static void
624
+ BigDecimal_count_precision_and_scale(VALUE self, ssize_t *out_precision, ssize_t *out_scale)
625
+ {
626
+ ENTER(1);
627
+ Real *p;
628
+ GUARD_OBJ(p, GetVpValue(self, 1));
629
+ VpCountPrecisionAndScale(p, out_precision, out_scale);
630
+ }
631
+
628
632
  /*
629
633
  * call-seq:
630
634
  * precision -> integer
@@ -1485,7 +1489,8 @@ BigDecimal_add(VALUE self, VALUE r)
1485
1489
  return VpCheckGetValue(c);
1486
1490
  }
1487
1491
 
1488
- /* call-seq:
1492
+ /*
1493
+ * call-seq:
1489
1494
  * self - value -> bigdecimal
1490
1495
  *
1491
1496
  * Returns the \BigDecimal difference of +self+ and +value+:
@@ -1780,6 +1785,17 @@ BigDecimal_neg(VALUE self)
1780
1785
  return VpCheckGetValue(c);
1781
1786
  }
1782
1787
 
1788
+ /*
1789
+ * call-seq:
1790
+ * a * b -> bigdecimal
1791
+ *
1792
+ * Multiply by the specified value.
1793
+ *
1794
+ * The result precision will be the precision of the sum of each precision.
1795
+ *
1796
+ * See BigDecimal#mult.
1797
+ */
1798
+
1783
1799
  static VALUE
1784
1800
  BigDecimal_mult(VALUE self, VALUE r)
1785
1801
  {
@@ -1807,55 +1823,6 @@ BigDecimal_mult(VALUE self, VALUE r)
1807
1823
  return VpCheckGetValue(c);
1808
1824
  }
1809
1825
 
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
1826
  static VALUE BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod);
1860
1827
 
1861
1828
  /* call-seq:
@@ -1873,20 +1840,15 @@ static VALUE
1873
1840
  BigDecimal_div(VALUE self, VALUE r)
1874
1841
  /* For c = self/r: with round operation */
1875
1842
  {
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]));
1843
+ if (
1844
+ !is_kind_of_BigDecimal(r) &&
1845
+ !RB_INTEGER_TYPE_P(r) &&
1846
+ !RB_TYPE_P(r, T_FLOAT) &&
1847
+ !RB_TYPE_P(r, T_RATIONAL)
1848
+ ) {
1849
+ return DoSomeOne(self, r, '/');
1888
1850
  }
1889
- return VpCheckGetValue(c);
1851
+ return BigDecimal_div2(self, r, INT2FIX(0));
1890
1852
  }
1891
1853
 
1892
1854
  static VALUE BigDecimal_round(int argc, VALUE *argv, VALUE self);
@@ -2042,8 +2004,8 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod)
2042
2004
  }
2043
2005
 
2044
2006
  /* call-seq:
2045
- * a % b
2046
- * a.modulo(b)
2007
+ * a % b
2008
+ * a.modulo(b)
2047
2009
  *
2048
2010
  * Returns the modulus from dividing by b.
2049
2011
  *
@@ -2116,7 +2078,7 @@ BigDecimal_divremain(VALUE self, VALUE r, Real **dv, Real **rv)
2116
2078
  }
2117
2079
 
2118
2080
  /* call-seq:
2119
- * remainder(value)
2081
+ * remainder(value)
2120
2082
  *
2121
2083
  * Returns the remainder from dividing by the value.
2122
2084
  *
@@ -2133,7 +2095,7 @@ BigDecimal_remainder(VALUE self, VALUE r) /* remainder */
2133
2095
  }
2134
2096
 
2135
2097
  /* call-seq:
2136
- * divmod(value)
2098
+ * divmod(value)
2137
2099
  *
2138
2100
  * Divides by the specified value, and returns the quotient and modulus
2139
2101
  * as BigDecimal numbers. The quotient is rounded towards negative infinity.
@@ -2176,6 +2138,9 @@ BigDecimal_div2(VALUE self, VALUE b, VALUE n)
2176
2138
  {
2177
2139
  ENTER(5);
2178
2140
  SIGNED_VALUE ix;
2141
+ Real *res = NULL;
2142
+ Real *av = NULL, *bv = NULL, *cv = NULL;
2143
+ size_t mx, pl;
2179
2144
 
2180
2145
  if (NIL_P(n)) { /* div in Float sense */
2181
2146
  Real *div = NULL;
@@ -2188,33 +2153,49 @@ BigDecimal_div2(VALUE self, VALUE b, VALUE n)
2188
2153
 
2189
2154
  /* div in BigDecimal sense */
2190
2155
  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));
2156
+
2157
+ pl = VpSetPrecLimit(0);
2158
+ if (ix == 0) ix = pl;
2159
+
2160
+ GUARD_OBJ(av, GetVpValue(self, 1));
2161
+ if (RB_FLOAT_TYPE_P(b) && ix > BIGDECIMAL_DOUBLE_FIGURES) {
2203
2162
  /* TODO: I want to refactor this precision control for a float value later
2204
2163
  * by introducing an implicit conversion function instead of
2205
2164
  * 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);
2165
+ GUARD_OBJ(bv, GetVpValueWithPrec(b, BIGDECIMAL_DOUBLE_FIGURES, 1));
2166
+ }
2167
+ else {
2168
+ GUARD_OBJ(bv, GetVpValueWithPrec(b, ix, 1));
2169
+ }
2170
+
2171
+ if (ix == 0) {
2172
+ ssize_t a_prec, b_prec;
2173
+ VpCountPrecisionAndScale(av, &a_prec, NULL);
2174
+ VpCountPrecisionAndScale(bv, &b_prec, NULL);
2175
+ ix = ((a_prec > b_prec) ? a_prec : b_prec) + BIGDECIMAL_DOUBLE_FIGURES;
2176
+ if (2 * BIGDECIMAL_DOUBLE_FIGURES > ix)
2177
+ ix = 2 * BIGDECIMAL_DOUBLE_FIGURES;
2178
+ }
2179
+
2180
+ // VpDivd needs 2 extra DECDIGs. One more is needed for rounding.
2181
+ GUARD_OBJ(cv, NewZeroWrapLimited(1, ix + 3 * VpBaseFig()));
2182
+
2183
+ mx = bv->Prec + cv->MaxPrec - 1;
2184
+ if (mx <= av->Prec) mx = av->Prec + 1;
2185
+ GUARD_OBJ(res, NewZeroWrapNolimit(1, mx * VpBaseFig()));
2186
+ VpDivd(cv, res, av, bv);
2187
+ VpSetPrecLimit(pl);
2188
+ if (!VpIsZero(res)) {
2189
+ // Remainder value affects rounding result.
2190
+ // ROUND_UP cv = 0.1e0 with ix=10 will be:
2191
+ // 0.1e0 if remainder == 0
2192
+ // 0.1000000001e0 if remainder != 0
2193
+ size_t idx = roomof(ix, BASE_FIG);
2194
+ while (cv->Prec <= idx) cv->frac[cv->Prec++] = 0;
2195
+ if (cv->frac[idx] == 0 || cv->frac[idx] == HALF_BASE) cv->frac[idx]++;
2217
2196
  }
2197
+ VpLeftRound(cv, VpGetRoundMode(), ix);
2198
+ return VpCheckGetValue(cv);
2218
2199
  }
2219
2200
 
2220
2201
  /*
@@ -2305,7 +2286,7 @@ BigDecimal_add2(VALUE self, VALUE b, VALUE n)
2305
2286
  }
2306
2287
 
2307
2288
  /* call-seq:
2308
- * sub(value, digits) -> bigdecimal
2289
+ * sub(value, digits) -> bigdecimal
2309
2290
  *
2310
2291
  * Subtract the specified value.
2311
2292
  *
@@ -2404,7 +2385,7 @@ BigDecimal_abs(VALUE self)
2404
2385
  }
2405
2386
 
2406
2387
  /* call-seq:
2407
- * sqrt(n)
2388
+ * sqrt(n)
2408
2389
  *
2409
2390
  * Returns the square root of the value.
2410
2391
  *
@@ -2445,10 +2426,10 @@ BigDecimal_fix(VALUE self)
2445
2426
  }
2446
2427
 
2447
2428
  /* call-seq:
2448
- * round(n, mode)
2429
+ * round(n, mode)
2449
2430
  *
2450
2431
  * 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.
2432
+ * BigDecimal if n is specified and positive, or as an Integer if it isn't.
2452
2433
  *
2453
2434
  * BigDecimal('3.14159').round #=> 3
2454
2435
  * BigDecimal('8.7').round #=> 9
@@ -2456,6 +2437,7 @@ BigDecimal_fix(VALUE self)
2456
2437
  *
2457
2438
  * BigDecimal('3.14159').round(2).class.name #=> "BigDecimal"
2458
2439
  * BigDecimal('3.14159').round.class.name #=> "Integer"
2440
+ * BigDecimal('3.14159').round(0).class.name #=> "Integer"
2459
2441
  *
2460
2442
  * If n is specified and positive, the fractional part of the result has no
2461
2443
  * more than that many digits.
@@ -2522,7 +2504,7 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
2522
2504
  }
2523
2505
 
2524
2506
  /* call-seq:
2525
- * truncate(n)
2507
+ * truncate(n)
2526
2508
  *
2527
2509
  * Truncate to the nearest integer (by default), returning the result as a
2528
2510
  * BigDecimal.
@@ -2584,7 +2566,7 @@ BigDecimal_frac(VALUE self)
2584
2566
  }
2585
2567
 
2586
2568
  /* call-seq:
2587
- * floor(n)
2569
+ * floor(n)
2588
2570
  *
2589
2571
  * Return the largest integer less than or equal to the value, as a BigDecimal.
2590
2572
  *
@@ -2631,7 +2613,7 @@ BigDecimal_floor(int argc, VALUE *argv, VALUE self)
2631
2613
  }
2632
2614
 
2633
2615
  /* call-seq:
2634
- * ceil(n)
2616
+ * ceil(n)
2635
2617
  *
2636
2618
  * Return the smallest integer greater than or equal to the value, as a BigDecimal.
2637
2619
  *
@@ -2674,7 +2656,7 @@ BigDecimal_ceil(int argc, VALUE *argv, VALUE self)
2674
2656
  }
2675
2657
 
2676
2658
  /* call-seq:
2677
- * to_s(s)
2659
+ * to_s(s)
2678
2660
  *
2679
2661
  * Converts the value to a string.
2680
2662
  *
@@ -2984,8 +2966,8 @@ bigdecimal_power_by_bigdecimal(Real const* x, Real const* exp, ssize_t const n)
2984
2966
  }
2985
2967
 
2986
2968
  /* call-seq:
2987
- * power(n)
2988
- * power(n, prec)
2969
+ * power(n)
2970
+ * power(n, prec)
2989
2971
  *
2990
2972
  * Returns the value raised to the power of n.
2991
2973
  *
@@ -3257,10 +3239,11 @@ BigDecimal_initialize_copy(VALUE self, VALUE other)
3257
3239
  return self;
3258
3240
  }
3259
3241
 
3242
+ /* :nodoc: */
3260
3243
  static VALUE
3261
3244
  BigDecimal_clone(VALUE self)
3262
3245
  {
3263
- return self;
3246
+ return self;
3264
3247
  }
3265
3248
 
3266
3249
  #ifdef HAVE_RB_OPTS_EXCEPTION_P
@@ -3758,6 +3741,12 @@ f_BigDecimal(int argc, VALUE *argv, VALUE self)
3758
3741
  return rb_convert_to_BigDecimal(val, digs, exception);
3759
3742
  }
3760
3743
 
3744
+ /* call-seq:
3745
+ * BigDecimal.interpret_loosely(string) -> bigdecimal
3746
+ *
3747
+ * Returns the +BigDecimal+ converted loosely from +string+.
3748
+ */
3749
+
3761
3750
  static VALUE
3762
3751
  BigDecimal_s_interpret_loosely(VALUE klass, VALUE str)
3763
3752
  {
@@ -3769,8 +3758,9 @@ BigDecimal_s_interpret_loosely(VALUE klass, VALUE str)
3769
3758
  return VpCheckGetValue(vp);
3770
3759
  }
3771
3760
 
3772
- /* call-seq:
3773
- * BigDecimal.limit(digits)
3761
+ /*
3762
+ * call-seq:
3763
+ * BigDecimal.limit(digits)
3774
3764
  *
3775
3765
  * Limit the number of significant digits in newly created BigDecimal
3776
3766
  * numbers to the specified value. Rounding is performed as necessary,
@@ -3904,7 +3894,7 @@ BigDecimal_save_limit(VALUE self)
3904
3894
  }
3905
3895
 
3906
3896
  /* call-seq:
3907
- * BigMath.exp(decimal, numeric) -> BigDecimal
3897
+ * BigMath.exp(decimal, numeric) -> BigDecimal
3908
3898
  *
3909
3899
  * Computes the value of e (the base of natural logarithms) raised to the
3910
3900
  * power of +decimal+, to the specified number of digits of precision.
@@ -4035,7 +4025,7 @@ BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec)
4035
4025
  }
4036
4026
 
4037
4027
  /* call-seq:
4038
- * BigMath.log(decimal, numeric) -> BigDecimal
4028
+ * BigMath.log(decimal, numeric) -> BigDecimal
4039
4029
  *
4040
4030
  * Computes the natural logarithm of +decimal+ to the specified number of
4041
4031
  * digits of precision, +numeric+.
@@ -4238,6 +4228,17 @@ BigDecimal_negative_zero(void)
4238
4228
  return BIGDECIMAL_NEGATIVE_ZERO;
4239
4229
  }
4240
4230
 
4231
+ static inline VALUE
4232
+ BigDecimal_literal(const char *str)
4233
+ {
4234
+ VALUE arg = rb_str_new_cstr(str);
4235
+ VALUE val = f_BigDecimal(1, &arg, rb_cBigDecimal);
4236
+ rb_gc_register_mark_object(val);
4237
+ return val;
4238
+ }
4239
+
4240
+ #define BIGDECIMAL_LITERAL(var, val) (BIGDECIMAL_ ## var = BigDecimal_literal(#val))
4241
+
4241
4242
  /* Document-class: BigDecimal
4242
4243
  * BigDecimal provides arbitrary-precision floating point decimal arithmetic.
4243
4244
  *
@@ -4394,7 +4395,6 @@ Init_bigdecimal(void)
4394
4395
  #ifdef HAVE_RB_EXT_RACTOR_SAFE
4395
4396
  rb_ext_ractor_safe(true);
4396
4397
  #endif
4397
- VALUE arg;
4398
4398
 
4399
4399
  id_BigDecimal_exception_mode = rb_intern_const("BigDecimal.exception_mode");
4400
4400
  id_BigDecimal_rounding_mode = rb_intern_const("BigDecimal.rounding_mode");
@@ -4532,33 +4532,19 @@ Init_bigdecimal(void)
4532
4532
  rb_define_const(rb_cBigDecimal, "SIGN_NEGATIVE_INFINITE", INT2FIX(VP_SIGN_NEGATIVE_INFINITE));
4533
4533
 
4534
4534
  /* 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);
4535
+ BIGDECIMAL_LITERAL(POSITIVE_ZERO, +0);
4538
4536
 
4539
4537
  /* 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);
4538
+ BIGDECIMAL_LITERAL(NEGATIVE_ZERO, -0);
4543
4539
 
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);
4540
+ /* Positive infinity[rdoc-ref:BigDecimal@Infinity] value. */
4541
+ rb_define_const(rb_cBigDecimal, "INFINITY", BIGDECIMAL_LITERAL(POSITIVE_INFINITY, +Infinity));
4548
4542
 
4549
4543
  /* 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);
4544
+ BIGDECIMAL_LITERAL(NEGATIVE_INFINITY, -Infinity);
4558
4545
 
4559
- /* Special value constants */
4560
- rb_define_const(rb_cBigDecimal, "INFINITY", BIGDECIMAL_POSITIVE_INFINITY);
4561
- rb_define_const(rb_cBigDecimal, "NAN", BIGDECIMAL_NAN);
4546
+ /* '{Not a Number}[rdoc-ref:BigDecimal@Not+a+Number]' value. */
4547
+ rb_define_const(rb_cBigDecimal, "NAN", BIGDECIMAL_LITERAL(NAN, NaN));
4562
4548
 
4563
4549
  /* instance methods */
4564
4550
  rb_define_method(rb_cBigDecimal, "precs", BigDecimal_prec, 0);
@@ -5203,6 +5189,48 @@ bigdecimal_parse_special_string(const char *str)
5203
5189
  return NULL;
5204
5190
  }
5205
5191
 
5192
+ struct VpCtoV_args {
5193
+ Real *a;
5194
+ const char *int_chr;
5195
+ size_t ni;
5196
+ const char *frac;
5197
+ size_t nf;
5198
+ const char *exp_chr;
5199
+ size_t ne;
5200
+ };
5201
+
5202
+ static VALUE
5203
+ call_VpCtoV(VALUE arg)
5204
+ {
5205
+ struct VpCtoV_args *x = (struct VpCtoV_args *)arg;
5206
+ return (VALUE)VpCtoV(x->a, x->int_chr, x->ni, x->frac, x->nf, x->exp_chr, x->ne);
5207
+ }
5208
+
5209
+ static int
5210
+ 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)
5211
+ {
5212
+ struct VpCtoV_args args;
5213
+ int state = 0;
5214
+
5215
+ args.a = a;
5216
+ args.int_chr = int_chr;
5217
+ args.ni = ni;
5218
+ args.frac = frac;
5219
+ args.nf = nf;
5220
+ args.exp_chr = exp_chr;
5221
+ args.ne = ne;
5222
+
5223
+ VALUE result = rb_protect(call_VpCtoV, (VALUE)&args, &state);
5224
+ if (state) {
5225
+ if (free_on_error) {
5226
+ rbd_free_struct(a);
5227
+ }
5228
+ rb_jump_tag(state);
5229
+ }
5230
+
5231
+ return (int)result;
5232
+ }
5233
+
5206
5234
  /*
5207
5235
  * Allocates variable.
5208
5236
  * [Input]
@@ -5220,7 +5248,7 @@ VP_EXPORT Real *
5220
5248
  VpAlloc(size_t mx, const char *szVal, int strict_p, int exc)
5221
5249
  {
5222
5250
  const char *orig_szVal = szVal;
5223
- size_t i, j, ni, ipf, nf, ipe, ne, dot_seen, exp_seen, nalloc;
5251
+ size_t i, j, ni, ipf, nf, ipe, ne, exp_seen, nalloc;
5224
5252
  size_t len;
5225
5253
  char v, *psz;
5226
5254
  int sign=1;
@@ -5306,13 +5334,11 @@ VpAlloc(size_t mx, const char *szVal, int strict_p, int exc)
5306
5334
  ne = 0; /* number of digits in the exponential part */
5307
5335
  ipf = 0; /* index of the beginning of the fractional part */
5308
5336
  ipe = 0; /* index of the beginning of the exponential part */
5309
- dot_seen = 0;
5310
5337
  exp_seen = 0;
5311
5338
 
5312
5339
  if (v != '\0') {
5313
5340
  /* Scanning fractional part */
5314
5341
  if ((psz[i] = szVal[j]) == '.') {
5315
- dot_seen = 1;
5316
5342
  ++i;
5317
5343
  ++j;
5318
5344
  ipf = i;
@@ -5328,9 +5354,6 @@ VpAlloc(size_t mx, const char *szVal, int strict_p, int exc)
5328
5354
  }
5329
5355
  if (!strict_p) {
5330
5356
  v = psz[i] = '\0';
5331
- if (nf == 0) {
5332
- dot_seen = 0;
5333
- }
5334
5357
  break;
5335
5358
  }
5336
5359
  goto invalid_value;
@@ -5401,7 +5424,7 @@ VpAlloc(size_t mx, const char *szVal, int strict_p, int exc)
5401
5424
 
5402
5425
  psz[i] = '\0';
5403
5426
 
5404
- if (strict_p && (((ni == 0 || dot_seen) && nf == 0) || (exp_seen && ne == 0))) {
5427
+ if (strict_p && ((ni == 0 && nf == 0) || (exp_seen && ne == 0))) {
5405
5428
  VALUE str;
5406
5429
  invalid_value:
5407
5430
  if (!strict_p) {
@@ -5422,7 +5445,7 @@ VpAlloc(size_t mx, const char *szVal, int strict_p, int exc)
5422
5445
  vp = rbd_allocate_struct(len);
5423
5446
  vp->MaxPrec = len; /* set max precision */
5424
5447
  VpSetZero(vp, sign);
5425
- VpCtoV(vp, psz, ni, psz + ipf, nf, psz + ipe, ne);
5448
+ protected_VpCtoV(vp, psz, ni, psz + ipf, nf, psz + ipe, ne, true);
5426
5449
  rb_str_resize(buf, 0);
5427
5450
  return vp;
5428
5451
  }
@@ -6112,7 +6135,7 @@ VpDivd(Real *c, Real *r, Real *a, Real *b)
6112
6135
  word_c = c->MaxPrec;
6113
6136
  word_r = r->MaxPrec;
6114
6137
 
6115
- if (word_a >= word_r) goto space_error;
6138
+ if (word_a >= word_r || word_b + word_c - 2 >= word_r) goto space_error;
6116
6139
 
6117
6140
  ind_r = 1;
6118
6141
  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,7 +1,7 @@
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.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenta Murata
@@ -9,7 +9,7 @@ authors:
9
9
  - Shigeo Kobayashi
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-03-14 00:00:00.000000000 Z
12
+ date: 1980-01-02 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: This library provides arbitrary-precision decimal floating-point number
15
15
  class.
@@ -44,7 +44,8 @@ homepage: https://github.com/ruby/bigdecimal
44
44
  licenses:
45
45
  - Ruby
46
46
  - BSD-2-Clause
47
- metadata: {}
47
+ metadata:
48
+ changelog_uri: https://github.com/ruby/bigdecimal/blob/master/CHANGES.md
48
49
  rdoc_options: []
49
50
  require_paths:
50
51
  - lib
@@ -59,7 +60,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
59
60
  - !ruby/object:Gem::Version
60
61
  version: '0'
61
62
  requirements: []
62
- rubygems_version: 3.6.0.dev
63
+ rubygems_version: 3.6.7
63
64
  specification_version: 4
64
65
  summary: Arbitrary-precision decimal floating-point number library.
65
66
  test_files: []