bigdecimal 3.1.9 → 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: 61cbb7233c53f76dca23b078090706faa4c5796f983d9b0bf207bb2d6c652625
4
- data.tar.gz: d7f68a343595d21e009f43ac47558d1805e004cefb85e6d0d423e46b307ba9fa
3
+ metadata.gz: 8737ecb678e63a8a9e0aefe2d0ea606a523915d08b66b69704967749e15e53bf
4
+ data.tar.gz: 0dec9bb1cf41f347efdc60b918bab5f14264e6fc082011870dbc62391fde1270
5
5
  SHA512:
6
- metadata.gz: 1b091bed99353940b359a3d4ba6639f67cfad6859efda3709007aec5310539c0159d333ee5fb425cdecde146d2bd4241b6e208ee273cde337f449d467a7593e4
7
- data.tar.gz: 0fa14bd118018db4d4b436375f804d62e6c894458a3fa555cafc2c8da2888bd03dea8206e3ce15a73f82b35afcd6c8285881d2c76acb14e9013cf1e72f7284c3
6
+ metadata.gz: ddacbb0df3b6976bc560fab41363de45e4776c6e56d884a2c00a71015b838ff83d2a26b87e4af63d3e60fff27f6e90638f7cd6b363c62d06c78ac4c8250d6d5a
7
+ data.tar.gz: bc4ee4ace918f04364f882b69acb9c60bca9abc2405f426bbaa5831af21a9508c02c73c1f7302a3f25d387b7518d42095bc7bcbb817151e84ca2b9b0ce6889b5
@@ -31,7 +31,7 @@
31
31
  #include "bits.h"
32
32
  #include "static_assert.h"
33
33
 
34
- #define BIGDECIMAL_VERSION "3.1.9"
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+:
@@ -1818,55 +1823,6 @@ BigDecimal_mult(VALUE self, VALUE r)
1818
1823
  return VpCheckGetValue(c);
1819
1824
  }
1820
1825
 
1821
- static VALUE
1822
- BigDecimal_divide(VALUE self, VALUE r, Real **c, Real **res, Real **div)
1823
- /* For c = self.div(r): with round operation */
1824
- {
1825
- ENTER(5);
1826
- Real *a, *b;
1827
- ssize_t a_prec, b_prec;
1828
- size_t mx;
1829
-
1830
- TypedData_Get_Struct(self, Real, &BigDecimal_data_type, a);
1831
- SAVE(a);
1832
-
1833
- VALUE rr = r;
1834
- if (is_kind_of_BigDecimal(rr)) {
1835
- /* do nothing */
1836
- }
1837
- else if (RB_INTEGER_TYPE_P(r)) {
1838
- rr = rb_inum_convert_to_BigDecimal(r, 0, true);
1839
- }
1840
- else if (RB_TYPE_P(r, T_FLOAT)) {
1841
- rr = rb_float_convert_to_BigDecimal(r, 0, true);
1842
- }
1843
- else if (RB_TYPE_P(r, T_RATIONAL)) {
1844
- rr = rb_rational_convert_to_BigDecimal(r, a->Prec*BASE_FIG, true);
1845
- }
1846
-
1847
- if (!is_kind_of_BigDecimal(rr)) {
1848
- return DoSomeOne(self, r, '/');
1849
- }
1850
-
1851
- TypedData_Get_Struct(rr, Real, &BigDecimal_data_type, b);
1852
- SAVE(b);
1853
- *div = b;
1854
-
1855
- BigDecimal_count_precision_and_scale(self, &a_prec, NULL);
1856
- BigDecimal_count_precision_and_scale(rr, &b_prec, NULL);
1857
- mx = (a_prec > b_prec) ? a_prec : b_prec;
1858
- mx *= 2;
1859
-
1860
- if (2*BIGDECIMAL_DOUBLE_FIGURES > mx)
1861
- mx = 2*BIGDECIMAL_DOUBLE_FIGURES;
1862
-
1863
- GUARD_OBJ((*c), NewZeroWrapNolimit(1, mx + 2*BASE_FIG));
1864
- GUARD_OBJ((*res), NewZeroWrapNolimit(1, (mx + 1)*2 + 2*BASE_FIG));
1865
- VpDivd(*c, *res, a, b);
1866
-
1867
- return Qnil;
1868
- }
1869
-
1870
1826
  static VALUE BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod);
1871
1827
 
1872
1828
  /* call-seq:
@@ -1884,20 +1840,15 @@ static VALUE
1884
1840
  BigDecimal_div(VALUE self, VALUE r)
1885
1841
  /* For c = self/r: with round operation */
1886
1842
  {
1887
- ENTER(5);
1888
- Real *c=NULL, *res=NULL, *div = NULL;
1889
- r = BigDecimal_divide(self, r, &c, &res, &div);
1890
- if (!NIL_P(r)) return r; /* coerced by other */
1891
- SAVE(c); SAVE(res); SAVE(div);
1892
- /* a/b = c + r/b */
1893
- /* c xxxxx
1894
- r 00000yyyyy ==> (y/b)*BASE >= HALF_BASE
1895
- */
1896
- /* Round */
1897
- if (VpHasVal(div)) { /* frac[0] must be zero for NaN,INF,Zero */
1898
- 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, '/');
1899
1850
  }
1900
- return VpCheckGetValue(c);
1851
+ return BigDecimal_div2(self, r, INT2FIX(0));
1901
1852
  }
1902
1853
 
1903
1854
  static VALUE BigDecimal_round(int argc, VALUE *argv, VALUE self);
@@ -2053,8 +2004,8 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod)
2053
2004
  }
2054
2005
 
2055
2006
  /* call-seq:
2056
- * a % b
2057
- * a.modulo(b)
2007
+ * a % b
2008
+ * a.modulo(b)
2058
2009
  *
2059
2010
  * Returns the modulus from dividing by b.
2060
2011
  *
@@ -2127,7 +2078,7 @@ BigDecimal_divremain(VALUE self, VALUE r, Real **dv, Real **rv)
2127
2078
  }
2128
2079
 
2129
2080
  /* call-seq:
2130
- * remainder(value)
2081
+ * remainder(value)
2131
2082
  *
2132
2083
  * Returns the remainder from dividing by the value.
2133
2084
  *
@@ -2144,7 +2095,7 @@ BigDecimal_remainder(VALUE self, VALUE r) /* remainder */
2144
2095
  }
2145
2096
 
2146
2097
  /* call-seq:
2147
- * divmod(value)
2098
+ * divmod(value)
2148
2099
  *
2149
2100
  * Divides by the specified value, and returns the quotient and modulus
2150
2101
  * as BigDecimal numbers. The quotient is rounded towards negative infinity.
@@ -2187,6 +2138,9 @@ BigDecimal_div2(VALUE self, VALUE b, VALUE n)
2187
2138
  {
2188
2139
  ENTER(5);
2189
2140
  SIGNED_VALUE ix;
2141
+ Real *res = NULL;
2142
+ Real *av = NULL, *bv = NULL, *cv = NULL;
2143
+ size_t mx, pl;
2190
2144
 
2191
2145
  if (NIL_P(n)) { /* div in Float sense */
2192
2146
  Real *div = NULL;
@@ -2199,33 +2153,49 @@ BigDecimal_div2(VALUE self, VALUE b, VALUE n)
2199
2153
 
2200
2154
  /* div in BigDecimal sense */
2201
2155
  ix = check_int_precision(n);
2202
- if (ix == 0) {
2203
- return BigDecimal_div(self, b);
2204
- }
2205
- else {
2206
- Real *res = NULL;
2207
- Real *av = NULL, *bv = NULL, *cv = NULL;
2208
- size_t mx = ix + VpBaseFig()*2;
2209
- size_t b_prec = ix;
2210
- size_t pl = VpSetPrecLimit(0);
2211
-
2212
- GUARD_OBJ(cv, NewZeroWrapLimited(1, mx + VpBaseFig()));
2213
- 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) {
2214
2162
  /* TODO: I want to refactor this precision control for a float value later
2215
2163
  * by introducing an implicit conversion function instead of
2216
2164
  * GetVpValueWithPrec. */
2217
- if (RB_FLOAT_TYPE_P(b) && b_prec > BIGDECIMAL_DOUBLE_FIGURES) {
2218
- b_prec = BIGDECIMAL_DOUBLE_FIGURES;
2219
- }
2220
- GUARD_OBJ(bv, GetVpValueWithPrec(b, b_prec, 1));
2221
- mx = av->Prec + bv->Prec + 2;
2222
- if (mx <= cv->MaxPrec) mx = cv->MaxPrec + 1;
2223
- GUARD_OBJ(res, NewZeroWrapNolimit(1, (mx * 2 + 2)*VpBaseFig()));
2224
- VpDivd(cv, res, av, bv);
2225
- VpSetPrecLimit(pl);
2226
- VpLeftRound(cv, VpGetRoundMode(), ix);
2227
- 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]++;
2228
2196
  }
2197
+ VpLeftRound(cv, VpGetRoundMode(), ix);
2198
+ return VpCheckGetValue(cv);
2229
2199
  }
2230
2200
 
2231
2201
  /*
@@ -2316,7 +2286,7 @@ BigDecimal_add2(VALUE self, VALUE b, VALUE n)
2316
2286
  }
2317
2287
 
2318
2288
  /* call-seq:
2319
- * sub(value, digits) -> bigdecimal
2289
+ * sub(value, digits) -> bigdecimal
2320
2290
  *
2321
2291
  * Subtract the specified value.
2322
2292
  *
@@ -2415,7 +2385,7 @@ BigDecimal_abs(VALUE self)
2415
2385
  }
2416
2386
 
2417
2387
  /* call-seq:
2418
- * sqrt(n)
2388
+ * sqrt(n)
2419
2389
  *
2420
2390
  * Returns the square root of the value.
2421
2391
  *
@@ -2456,7 +2426,7 @@ BigDecimal_fix(VALUE self)
2456
2426
  }
2457
2427
 
2458
2428
  /* call-seq:
2459
- * round(n, mode)
2429
+ * round(n, mode)
2460
2430
  *
2461
2431
  * Round to the nearest integer (by default), returning the result as a
2462
2432
  * BigDecimal if n is specified and positive, or as an Integer if it isn't.
@@ -2534,7 +2504,7 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
2534
2504
  }
2535
2505
 
2536
2506
  /* call-seq:
2537
- * truncate(n)
2507
+ * truncate(n)
2538
2508
  *
2539
2509
  * Truncate to the nearest integer (by default), returning the result as a
2540
2510
  * BigDecimal.
@@ -2596,7 +2566,7 @@ BigDecimal_frac(VALUE self)
2596
2566
  }
2597
2567
 
2598
2568
  /* call-seq:
2599
- * floor(n)
2569
+ * floor(n)
2600
2570
  *
2601
2571
  * Return the largest integer less than or equal to the value, as a BigDecimal.
2602
2572
  *
@@ -2643,7 +2613,7 @@ BigDecimal_floor(int argc, VALUE *argv, VALUE self)
2643
2613
  }
2644
2614
 
2645
2615
  /* call-seq:
2646
- * ceil(n)
2616
+ * ceil(n)
2647
2617
  *
2648
2618
  * Return the smallest integer greater than or equal to the value, as a BigDecimal.
2649
2619
  *
@@ -2686,7 +2656,7 @@ BigDecimal_ceil(int argc, VALUE *argv, VALUE self)
2686
2656
  }
2687
2657
 
2688
2658
  /* call-seq:
2689
- * to_s(s)
2659
+ * to_s(s)
2690
2660
  *
2691
2661
  * Converts the value to a string.
2692
2662
  *
@@ -2996,8 +2966,8 @@ bigdecimal_power_by_bigdecimal(Real const* x, Real const* exp, ssize_t const n)
2996
2966
  }
2997
2967
 
2998
2968
  /* call-seq:
2999
- * power(n)
3000
- * power(n, prec)
2969
+ * power(n)
2970
+ * power(n, prec)
3001
2971
  *
3002
2972
  * Returns the value raised to the power of n.
3003
2973
  *
@@ -3788,8 +3758,9 @@ BigDecimal_s_interpret_loosely(VALUE klass, VALUE str)
3788
3758
  return VpCheckGetValue(vp);
3789
3759
  }
3790
3760
 
3791
- /* call-seq:
3792
- * BigDecimal.limit(digits)
3761
+ /*
3762
+ * call-seq:
3763
+ * BigDecimal.limit(digits)
3793
3764
  *
3794
3765
  * Limit the number of significant digits in newly created BigDecimal
3795
3766
  * numbers to the specified value. Rounding is performed as necessary,
@@ -3923,7 +3894,7 @@ BigDecimal_save_limit(VALUE self)
3923
3894
  }
3924
3895
 
3925
3896
  /* call-seq:
3926
- * BigMath.exp(decimal, numeric) -> BigDecimal
3897
+ * BigMath.exp(decimal, numeric) -> BigDecimal
3927
3898
  *
3928
3899
  * Computes the value of e (the base of natural logarithms) raised to the
3929
3900
  * power of +decimal+, to the specified number of digits of precision.
@@ -4054,7 +4025,7 @@ BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec)
4054
4025
  }
4055
4026
 
4056
4027
  /* call-seq:
4057
- * BigMath.log(decimal, numeric) -> BigDecimal
4028
+ * BigMath.log(decimal, numeric) -> BigDecimal
4058
4029
  *
4059
4030
  * Computes the natural logarithm of +decimal+ to the specified number of
4060
4031
  * digits of precision, +numeric+.
@@ -6164,7 +6135,7 @@ VpDivd(Real *c, Real *r, Real *a, Real *b)
6164
6135
  word_c = c->MaxPrec;
6165
6136
  word_r = r->MaxPrec;
6166
6137
 
6167
- if (word_a >= word_r) goto space_error;
6138
+ if (word_a >= word_r || word_b + word_c - 2 >= word_r) goto space_error;
6168
6139
 
6169
6140
  ind_r = 1;
6170
6141
  r->frac[0] = 0;
@@ -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
  #
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.9
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-12-25 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.
@@ -60,7 +60,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  requirements: []
63
- rubygems_version: 3.6.2
63
+ rubygems_version: 3.6.7
64
64
  specification_version: 4
65
65
  summary: Arbitrary-precision decimal floating-point number library.
66
66
  test_files: []