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 +4 -4
- data/bigdecimal.gemspec +2 -0
- data/ext/bigdecimal/bigdecimal.c +155 -137
- data/ext/bigdecimal/extconf.rb +11 -9
- data/ext/bigdecimal/missing.c +2 -1
- data/lib/bigdecimal/math.rb +1 -2
- data/lib/bigdecimal/util.rb +1 -1
- metadata +8 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d4fdad45c0e9519d352fa25d4134af80ce6897c8196bcb3bf0e25d6ebcea8918
|
|
4
|
+
data.tar.gz: ed56f36c2e5fd8cea29b0de49ac2c25edf186de643d69aff660677ada7a79ae8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2481253ce262ad322882ca3c3ae5c14eec4b4cc599c34c4aac0e71f3161cece17adce5b506fc94548018ab9605c411e1746d40bdc9f086ef3dfd085197ce7d15
|
|
7
|
+
data.tar.gz: cb3ee7815dd3d4f63271ffb09c09ff485dd9603b6fc5cb639416cf1f7c20df576aac5e53c891245bbc0a03789b4f2dcd514cf7e48c186f05f58600a799a5ed6e
|
data/bigdecimal.gemspec
CHANGED
data/ext/bigdecimal/bigdecimal.c
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
#include "bits.h"
|
|
32
32
|
#include "static_assert.h"
|
|
33
33
|
|
|
34
|
-
#define BIGDECIMAL_VERSION "3.
|
|
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
|
-
/*
|
|
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
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
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
|
|
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
|
-
*
|
|
2046
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
2988
|
-
*
|
|
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
|
-
|
|
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
|
-
/*
|
|
3773
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
/*
|
|
4560
|
-
rb_define_const(rb_cBigDecimal, "
|
|
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,
|
|
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 && ((
|
|
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
|
-
|
|
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;
|
data/ext/bigdecimal/extconf.rb
CHANGED
|
@@ -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
|
-
|
|
32
|
-
|
|
33
|
-
have_func("
|
|
34
|
-
have_func("
|
|
35
|
-
have_func("
|
|
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")
|
data/ext/bigdecimal/missing.c
CHANGED
data/lib/bigdecimal/math.rb
CHANGED
|
@@ -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)
|
|
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
|
#
|
data/lib/bigdecimal/util.rb
CHANGED
|
@@ -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
|
|
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.
|
|
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:
|
|
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.
|
|
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: []
|