bigdecimal 3.1.9 → 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: 61cbb7233c53f76dca23b078090706faa4c5796f983d9b0bf207bb2d6c652625
4
- data.tar.gz: d7f68a343595d21e009f43ac47558d1805e004cefb85e6d0d423e46b307ba9fa
3
+ metadata.gz: d4fdad45c0e9519d352fa25d4134af80ce6897c8196bcb3bf0e25d6ebcea8918
4
+ data.tar.gz: ed56f36c2e5fd8cea29b0de49ac2c25edf186de643d69aff660677ada7a79ae8
5
5
  SHA512:
6
- metadata.gz: 1b091bed99353940b359a3d4ba6639f67cfad6859efda3709007aec5310539c0159d333ee5fb425cdecde146d2bd4241b6e208ee273cde337f449d467a7593e4
7
- data.tar.gz: 0fa14bd118018db4d4b436375f804d62e6c894458a3fa555cafc2c8da2888bd03dea8206e3ce15a73f82b35afcd6c8285881d2c76acb14e9013cf1e72f7284c3
6
+ metadata.gz: 2481253ce262ad322882ca3c3ae5c14eec4b4cc599c34c4aac0e71f3161cece17adce5b506fc94548018ab9605c411e1746d40bdc9f086ef3dfd085197ce7d15
7
+ data.tar.gz: cb3ee7815dd3d4f63271ffb09c09ff485dd9603b6fc5cb639416cf1f7c20df576aac5e53c891245bbc0a03789b4f2dcd514cf7e48c186f05f58600a799a5ed6e
@@ -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.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+:
@@ -1818,55 +1819,6 @@ BigDecimal_mult(VALUE self, VALUE r)
1818
1819
  return VpCheckGetValue(c);
1819
1820
  }
1820
1821
 
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
1822
  static VALUE BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod);
1871
1823
 
1872
1824
  /* call-seq:
@@ -1884,20 +1836,15 @@ static VALUE
1884
1836
  BigDecimal_div(VALUE self, VALUE r)
1885
1837
  /* For c = self/r: with round operation */
1886
1838
  {
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]));
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, '/');
1899
1846
  }
1900
- return VpCheckGetValue(c);
1847
+ return BigDecimal_div2(self, r, INT2FIX(0));
1901
1848
  }
1902
1849
 
1903
1850
  static VALUE BigDecimal_round(int argc, VALUE *argv, VALUE self);
@@ -2053,8 +2000,8 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod)
2053
2000
  }
2054
2001
 
2055
2002
  /* call-seq:
2056
- * a % b
2057
- * a.modulo(b)
2003
+ * a % b
2004
+ * a.modulo(b)
2058
2005
  *
2059
2006
  * Returns the modulus from dividing by b.
2060
2007
  *
@@ -2127,7 +2074,7 @@ BigDecimal_divremain(VALUE self, VALUE r, Real **dv, Real **rv)
2127
2074
  }
2128
2075
 
2129
2076
  /* call-seq:
2130
- * remainder(value)
2077
+ * remainder(value)
2131
2078
  *
2132
2079
  * Returns the remainder from dividing by the value.
2133
2080
  *
@@ -2144,7 +2091,7 @@ BigDecimal_remainder(VALUE self, VALUE r) /* remainder */
2144
2091
  }
2145
2092
 
2146
2093
  /* call-seq:
2147
- * divmod(value)
2094
+ * divmod(value)
2148
2095
  *
2149
2096
  * Divides by the specified value, and returns the quotient and modulus
2150
2097
  * as BigDecimal numbers. The quotient is rounded towards negative infinity.
@@ -2187,6 +2134,9 @@ BigDecimal_div2(VALUE self, VALUE b, VALUE n)
2187
2134
  {
2188
2135
  ENTER(5);
2189
2136
  SIGNED_VALUE ix;
2137
+ Real *res = NULL;
2138
+ Real *av = NULL, *bv = NULL, *cv = NULL;
2139
+ size_t mx, pl;
2190
2140
 
2191
2141
  if (NIL_P(n)) { /* div in Float sense */
2192
2142
  Real *div = NULL;
@@ -2199,33 +2149,48 @@ BigDecimal_div2(VALUE self, VALUE b, VALUE n)
2199
2149
 
2200
2150
  /* div in BigDecimal sense */
2201
2151
  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));
2152
+
2153
+ pl = VpSetPrecLimit(0);
2154
+
2155
+ GUARD_OBJ(av, GetVpValue(self, 1));
2156
+ if (RB_FLOAT_TYPE_P(b) && ix > BIGDECIMAL_DOUBLE_FIGURES) {
2214
2157
  /* TODO: I want to refactor this precision control for a float value later
2215
2158
  * by introducing an implicit conversion function instead of
2216
2159
  * 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);
2160
+ GUARD_OBJ(bv, GetVpValueWithPrec(b, BIGDECIMAL_DOUBLE_FIGURES, 1));
2161
+ }
2162
+ else {
2163
+ GUARD_OBJ(bv, GetVpValueWithPrec(b, ix, 1));
2228
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);
2229
2194
  }
2230
2195
 
2231
2196
  /*
@@ -2316,7 +2281,7 @@ BigDecimal_add2(VALUE self, VALUE b, VALUE n)
2316
2281
  }
2317
2282
 
2318
2283
  /* call-seq:
2319
- * sub(value, digits) -> bigdecimal
2284
+ * sub(value, digits) -> bigdecimal
2320
2285
  *
2321
2286
  * Subtract the specified value.
2322
2287
  *
@@ -2415,7 +2380,7 @@ BigDecimal_abs(VALUE self)
2415
2380
  }
2416
2381
 
2417
2382
  /* call-seq:
2418
- * sqrt(n)
2383
+ * sqrt(n)
2419
2384
  *
2420
2385
  * Returns the square root of the value.
2421
2386
  *
@@ -2456,7 +2421,7 @@ BigDecimal_fix(VALUE self)
2456
2421
  }
2457
2422
 
2458
2423
  /* call-seq:
2459
- * round(n, mode)
2424
+ * round(n, mode)
2460
2425
  *
2461
2426
  * Round to the nearest integer (by default), returning the result as a
2462
2427
  * BigDecimal if n is specified and positive, or as an Integer if it isn't.
@@ -2534,7 +2499,7 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
2534
2499
  }
2535
2500
 
2536
2501
  /* call-seq:
2537
- * truncate(n)
2502
+ * truncate(n)
2538
2503
  *
2539
2504
  * Truncate to the nearest integer (by default), returning the result as a
2540
2505
  * BigDecimal.
@@ -2596,7 +2561,7 @@ BigDecimal_frac(VALUE self)
2596
2561
  }
2597
2562
 
2598
2563
  /* call-seq:
2599
- * floor(n)
2564
+ * floor(n)
2600
2565
  *
2601
2566
  * Return the largest integer less than or equal to the value, as a BigDecimal.
2602
2567
  *
@@ -2643,7 +2608,7 @@ BigDecimal_floor(int argc, VALUE *argv, VALUE self)
2643
2608
  }
2644
2609
 
2645
2610
  /* call-seq:
2646
- * ceil(n)
2611
+ * ceil(n)
2647
2612
  *
2648
2613
  * Return the smallest integer greater than or equal to the value, as a BigDecimal.
2649
2614
  *
@@ -2686,7 +2651,7 @@ BigDecimal_ceil(int argc, VALUE *argv, VALUE self)
2686
2651
  }
2687
2652
 
2688
2653
  /* call-seq:
2689
- * to_s(s)
2654
+ * to_s(s)
2690
2655
  *
2691
2656
  * Converts the value to a string.
2692
2657
  *
@@ -2996,8 +2961,8 @@ bigdecimal_power_by_bigdecimal(Real const* x, Real const* exp, ssize_t const n)
2996
2961
  }
2997
2962
 
2998
2963
  /* call-seq:
2999
- * power(n)
3000
- * power(n, prec)
2964
+ * power(n)
2965
+ * power(n, prec)
3001
2966
  *
3002
2967
  * Returns the value raised to the power of n.
3003
2968
  *
@@ -3788,8 +3753,9 @@ BigDecimal_s_interpret_loosely(VALUE klass, VALUE str)
3788
3753
  return VpCheckGetValue(vp);
3789
3754
  }
3790
3755
 
3791
- /* call-seq:
3792
- * BigDecimal.limit(digits)
3756
+ /*
3757
+ * call-seq:
3758
+ * BigDecimal.limit(digits)
3793
3759
  *
3794
3760
  * Limit the number of significant digits in newly created BigDecimal
3795
3761
  * numbers to the specified value. Rounding is performed as necessary,
@@ -3923,7 +3889,7 @@ BigDecimal_save_limit(VALUE self)
3923
3889
  }
3924
3890
 
3925
3891
  /* call-seq:
3926
- * BigMath.exp(decimal, numeric) -> BigDecimal
3892
+ * BigMath.exp(decimal, numeric) -> BigDecimal
3927
3893
  *
3928
3894
  * Computes the value of e (the base of natural logarithms) raised to the
3929
3895
  * power of +decimal+, to the specified number of digits of precision.
@@ -4054,7 +4020,7 @@ BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec)
4054
4020
  }
4055
4021
 
4056
4022
  /* call-seq:
4057
- * BigMath.log(decimal, numeric) -> BigDecimal
4023
+ * BigMath.log(decimal, numeric) -> BigDecimal
4058
4024
  *
4059
4025
  * Computes the natural logarithm of +decimal+ to the specified number of
4060
4026
  * digits of precision, +numeric+.
@@ -6164,7 +6130,7 @@ VpDivd(Real *c, Real *r, Real *a, Real *b)
6164
6130
  word_c = c->MaxPrec;
6165
6131
  word_r = r->MaxPrec;
6166
6132
 
6167
- if (word_a >= word_r) goto space_error;
6133
+ if (word_a >= word_r || word_b + word_c - 2 >= word_r) goto space_error;
6168
6134
 
6169
6135
  ind_r = 1;
6170
6136
  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,15 +1,16 @@
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.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-12-25 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.
@@ -46,6 +47,7 @@ licenses:
46
47
  - BSD-2-Clause
47
48
  metadata:
48
49
  changelog_uri: https://github.com/ruby/bigdecimal/blob/master/CHANGES.md
50
+ post_install_message:
49
51
  rdoc_options: []
50
52
  require_paths:
51
53
  - lib
@@ -60,7 +62,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
60
62
  - !ruby/object:Gem::Version
61
63
  version: '0'
62
64
  requirements: []
63
- rubygems_version: 3.6.2
65
+ rubygems_version: 3.5.10
66
+ signing_key:
64
67
  specification_version: 4
65
68
  summary: Arbitrary-precision decimal floating-point number library.
66
69
  test_files: []