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 +4 -4
- data/bigdecimal.gemspec +2 -0
- data/ext/bigdecimal/bigdecimal.c +166 -143
- 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 +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8737ecb678e63a8a9e0aefe2d0ea606a523915d08b66b69704967749e15e53bf
|
4
|
+
data.tar.gz: 0dec9bb1cf41f347efdc60b918bab5f14264e6fc082011870dbc62391fde1270
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ddacbb0df3b6976bc560fab41363de45e4776c6e56d884a2c00a71015b838ff83d2a26b87e4af63d3e60fff27f6e90638f7cd6b363c62d06c78ac4c8250d6d5a
|
7
|
+
data.tar.gz: bc4ee4ace918f04364f882b69acb9c60bca9abc2405f426bbaa5831af21a9508c02c73c1f7302a3f25d387b7518d42095bc7bcbb817151e84ca2b9b0ce6889b5
|
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.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
|
-
|
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
|
-
/*
|
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
|
-
|
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]));
|
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
|
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
|
-
*
|
2046
|
-
*
|
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
|
-
*
|
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
|
-
*
|
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
|
-
|
2192
|
-
|
2193
|
-
|
2194
|
-
|
2195
|
-
|
2196
|
-
|
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
|
-
|
2207
|
-
|
2208
|
-
|
2209
|
-
GUARD_OBJ(bv, GetVpValueWithPrec(b,
|
2210
|
-
|
2211
|
-
|
2212
|
-
|
2213
|
-
|
2214
|
-
|
2215
|
-
|
2216
|
-
|
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
|
-
*
|
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
|
-
*
|
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
|
-
*
|
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
|
-
*
|
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
|
-
*
|
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
|
-
*
|
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
|
-
*
|
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
|
-
*
|
2988
|
-
*
|
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
|
-
|
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
|
-
/*
|
3773
|
-
*
|
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
|
-
*
|
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
|
-
*
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
/*
|
4560
|
-
rb_define_const(rb_cBigDecimal, "
|
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,
|
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 && ((
|
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
|
-
|
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;
|
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,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bigdecimal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
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:
|
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.
|
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: []
|