bigdecimal 3.2.3 → 4.0.1
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/ext/bigdecimal/bigdecimal.c +40 -47
- data/lib/bigdecimal/jacobian.rb +2 -0
- data/lib/bigdecimal/ludcmp.rb +2 -0
- data/lib/bigdecimal/math.rb +785 -71
- data/lib/bigdecimal/newton.rb +2 -0
- data/lib/bigdecimal/util.rb +15 -14
- data/lib/bigdecimal.rb +98 -67
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3779ec68890d9353aa7e8910445435ce636a4bee3c398d46ba37798612a8b19f
|
|
4
|
+
data.tar.gz: f0829fbe026a8b008beb81e2b79d5efdbb66ada64eaebb1f5ce70b6f80a45fc3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 867235a805d627a8444b7029329e16b21c2702d421d59bacf2aae675b5d62cea9b517650ed1e5bc7e548c93b1b0310e5d382ae49dc61c94f8effe9fda9d26228
|
|
7
|
+
data.tar.gz: 36786ceef3f96ccd16e0c30c3a188c86f35b9e11d5c36587b62729b842eb37f49c6588b17b5c9f71c393016c08c90731b0f7b8a015188c2da1dc7156f988007e
|
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 "
|
|
34
|
+
#define BIGDECIMAL_VERSION "4.0.1"
|
|
35
35
|
|
|
36
36
|
/* #define ENABLE_NUMERIC_STRING */
|
|
37
37
|
|
|
@@ -252,10 +252,21 @@ static const rb_data_type_t BigDecimal_data_type = {
|
|
|
252
252
|
#endif
|
|
253
253
|
};
|
|
254
254
|
|
|
255
|
+
// TypedData_Wrap_Struct may fail if there is no memory, or GC.add_stress_to_class(BigDecimal) is set.
|
|
256
|
+
// We need to first allocate empty struct, allocate Real struct, and then set the data pointer.
|
|
257
|
+
typedef struct { VALUE _obj; } NULL_WRAPPED_VALUE;
|
|
258
|
+
static NULL_WRAPPED_VALUE
|
|
259
|
+
BigDecimal_alloc_empty_struct(VALUE klass)
|
|
260
|
+
{
|
|
261
|
+
return (NULL_WRAPPED_VALUE) { TypedData_Wrap_Struct(klass, &BigDecimal_data_type, NULL) };
|
|
262
|
+
}
|
|
263
|
+
|
|
255
264
|
static VALUE
|
|
256
|
-
BigDecimal_wrap_struct(
|
|
265
|
+
BigDecimal_wrap_struct(NULL_WRAPPED_VALUE v, Real *real)
|
|
257
266
|
{
|
|
258
|
-
VALUE obj =
|
|
267
|
+
VALUE obj = v._obj;
|
|
268
|
+
assert(RTYPEDDATA_DATA(obj) == NULL);
|
|
269
|
+
RTYPEDDATA_DATA(obj) = real;
|
|
259
270
|
RB_OBJ_FREEZE(obj);
|
|
260
271
|
return obj;
|
|
261
272
|
}
|
|
@@ -265,8 +276,9 @@ MAYBE_UNUSED(static inline BDVALUE rbd_allocate_struct_zero_wrap(int sign, size_
|
|
|
265
276
|
static BDVALUE
|
|
266
277
|
rbd_allocate_struct_zero_wrap(int sign, size_t const digits)
|
|
267
278
|
{
|
|
279
|
+
NULL_WRAPPED_VALUE null_wrapped = BigDecimal_alloc_empty_struct(rb_cBigDecimal);
|
|
268
280
|
Real *real = rbd_allocate_struct_zero(sign, digits);
|
|
269
|
-
return (BDVALUE) { BigDecimal_wrap_struct(
|
|
281
|
+
return (BDVALUE) { BigDecimal_wrap_struct(null_wrapped, real), real };
|
|
270
282
|
}
|
|
271
283
|
|
|
272
284
|
static inline int
|
|
@@ -388,37 +400,6 @@ BigDecimal_double_fig(VALUE self)
|
|
|
388
400
|
return INT2FIX(BIGDECIMAL_DOUBLE_FIGURES);
|
|
389
401
|
}
|
|
390
402
|
|
|
391
|
-
/* call-seq:
|
|
392
|
-
* precs -> array
|
|
393
|
-
*
|
|
394
|
-
* Returns an Array of two Integer values that represent platform-dependent
|
|
395
|
-
* internal storage properties.
|
|
396
|
-
*
|
|
397
|
-
* This method is deprecated and will be removed in the future.
|
|
398
|
-
* Instead, use BigDecimal#n_significant_digits for obtaining the number of
|
|
399
|
-
* significant digits in scientific notation, and BigDecimal#precision for
|
|
400
|
-
* obtaining the number of digits in decimal notation.
|
|
401
|
-
*
|
|
402
|
-
*/
|
|
403
|
-
|
|
404
|
-
static VALUE
|
|
405
|
-
BigDecimal_prec(VALUE self)
|
|
406
|
-
{
|
|
407
|
-
BDVALUE v;
|
|
408
|
-
VALUE obj;
|
|
409
|
-
|
|
410
|
-
rb_category_warn(RB_WARN_CATEGORY_DEPRECATED,
|
|
411
|
-
"BigDecimal#precs is deprecated and will be removed in the future; "
|
|
412
|
-
"use BigDecimal#precision instead.");
|
|
413
|
-
|
|
414
|
-
v = GetBDValueMust(self);
|
|
415
|
-
obj = rb_assoc_new(SIZET2NUM(v.real->Prec*VpBaseFig()),
|
|
416
|
-
SIZET2NUM(v.real->MaxPrec*VpBaseFig()));
|
|
417
|
-
|
|
418
|
-
RB_GC_GUARD(v.bigdecimal);
|
|
419
|
-
return obj;
|
|
420
|
-
}
|
|
421
|
-
|
|
422
403
|
static void
|
|
423
404
|
VpCountPrecisionAndScale(Real *p, ssize_t *out_precision, ssize_t *out_scale)
|
|
424
405
|
{
|
|
@@ -1041,9 +1022,10 @@ check_int_precision(VALUE v)
|
|
|
1041
1022
|
static NULLABLE_BDVALUE
|
|
1042
1023
|
CreateFromString(const char *str, VALUE klass, bool strict_p, bool raise_exception)
|
|
1043
1024
|
{
|
|
1025
|
+
NULL_WRAPPED_VALUE null_wrapped = BigDecimal_alloc_empty_struct(klass);
|
|
1044
1026
|
Real *pv = VpAlloc(str, strict_p, raise_exception);
|
|
1045
1027
|
if (!pv) return (NULLABLE_BDVALUE) { Qnil, NULL };
|
|
1046
|
-
return (NULLABLE_BDVALUE) { BigDecimal_wrap_struct(
|
|
1028
|
+
return (NULLABLE_BDVALUE) { BigDecimal_wrap_struct(null_wrapped, pv), pv };
|
|
1047
1029
|
}
|
|
1048
1030
|
|
|
1049
1031
|
static Real *
|
|
@@ -1720,15 +1702,25 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, NULLABLE_BDVALUE *div, NULLABLE_BDVALUE
|
|
|
1720
1702
|
*mod = (NULLABLE_BDVALUE) { nan, DATA_PTR(nan) };
|
|
1721
1703
|
goto Done;
|
|
1722
1704
|
}
|
|
1723
|
-
if (
|
|
1705
|
+
if (VpIsZero(a.real)) {
|
|
1724
1706
|
VALUE zero = BigDecimal_positive_zero();
|
|
1725
1707
|
*div = (NULLABLE_BDVALUE) { zero, DATA_PTR(zero) };
|
|
1726
1708
|
*mod = bdvalue_nullable(a);
|
|
1727
1709
|
goto Done;
|
|
1728
1710
|
}
|
|
1729
|
-
if (
|
|
1730
|
-
|
|
1731
|
-
|
|
1711
|
+
if (VpIsInf(b.real)) {
|
|
1712
|
+
if (!truncate && VpGetSign(a.real) * VpGetSign(b.real) < 0) {
|
|
1713
|
+
BDVALUE minus_one = NewZeroWrap(1, BASE_FIG);
|
|
1714
|
+
VpSetOne(minus_one.real);
|
|
1715
|
+
VpSetSign(minus_one.real, -1);
|
|
1716
|
+
RB_GC_GUARD(minus_one.bigdecimal);
|
|
1717
|
+
*div = bdvalue_nullable(minus_one);
|
|
1718
|
+
*mod = bdvalue_nullable(b);
|
|
1719
|
+
} else {
|
|
1720
|
+
VALUE zero = BigDecimal_positive_zero();
|
|
1721
|
+
*div = (NULLABLE_BDVALUE) { zero, DATA_PTR(zero) };
|
|
1722
|
+
*mod = bdvalue_nullable(a);
|
|
1723
|
+
}
|
|
1732
1724
|
goto Done;
|
|
1733
1725
|
}
|
|
1734
1726
|
|
|
@@ -1844,7 +1836,7 @@ BigDecimal_divmod(VALUE self, VALUE r)
|
|
|
1844
1836
|
NULLABLE_BDVALUE div, mod;
|
|
1845
1837
|
|
|
1846
1838
|
if (BigDecimal_DoDivmod(self, r, &div, &mod, false)) {
|
|
1847
|
-
return rb_assoc_new(CheckGetValue(bdvalue_nonnullable(div)), CheckGetValue(bdvalue_nonnullable(mod)));
|
|
1839
|
+
return rb_assoc_new(BigDecimal_to_i(CheckGetValue(bdvalue_nonnullable(div))), CheckGetValue(bdvalue_nonnullable(mod)));
|
|
1848
1840
|
}
|
|
1849
1841
|
return DoSomeOne(self,r,rb_intern("divmod"));
|
|
1850
1842
|
}
|
|
@@ -2484,7 +2476,7 @@ BigDecimal_decimal_shift(VALUE self, VALUE v)
|
|
|
2484
2476
|
prec = a.real->Prec + shiftDown;
|
|
2485
2477
|
c = NewZeroWrap(1, prec * BASE_FIG);
|
|
2486
2478
|
if (shift == 0) {
|
|
2487
|
-
VpAsgn(c.real, a.real,
|
|
2479
|
+
VpAsgn(c.real, a.real, 10);
|
|
2488
2480
|
} else if (shiftDown) {
|
|
2489
2481
|
DECDIG carry = 0;
|
|
2490
2482
|
exponentShift++;
|
|
@@ -2580,6 +2572,7 @@ check_exception(VALUE bd)
|
|
|
2580
2572
|
static VALUE
|
|
2581
2573
|
rb_uint64_convert_to_BigDecimal(uint64_t uval)
|
|
2582
2574
|
{
|
|
2575
|
+
NULL_WRAPPED_VALUE null_wrapped = BigDecimal_alloc_empty_struct(rb_cBigDecimal);
|
|
2583
2576
|
Real *vp;
|
|
2584
2577
|
if (uval == 0) {
|
|
2585
2578
|
vp = rbd_allocate_struct(1);
|
|
@@ -2621,7 +2614,7 @@ rb_uint64_convert_to_BigDecimal(uint64_t uval)
|
|
|
2621
2614
|
MEMCPY(vp->frac, buf + BIGDECIMAL_INT64_MAX_LENGTH - len, DECDIG, len);
|
|
2622
2615
|
}
|
|
2623
2616
|
|
|
2624
|
-
return BigDecimal_wrap_struct(
|
|
2617
|
+
return BigDecimal_wrap_struct(null_wrapped, vp);
|
|
2625
2618
|
}
|
|
2626
2619
|
|
|
2627
2620
|
static VALUE
|
|
@@ -2905,12 +2898,13 @@ rb_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception)
|
|
|
2905
2898
|
if (digs == SIZE_MAX)
|
|
2906
2899
|
return check_exception(val);
|
|
2907
2900
|
|
|
2901
|
+
NULL_WRAPPED_VALUE null_wrapped = BigDecimal_alloc_empty_struct(rb_cBigDecimal);
|
|
2908
2902
|
Real *vp;
|
|
2909
2903
|
TypedData_Get_Struct(val, Real, &BigDecimal_data_type, vp);
|
|
2910
2904
|
vp = VpCopy(NULL, vp);
|
|
2911
2905
|
RB_GC_GUARD(val);
|
|
2912
2906
|
|
|
2913
|
-
VALUE copy = BigDecimal_wrap_struct(
|
|
2907
|
+
VALUE copy = BigDecimal_wrap_struct(null_wrapped, vp);
|
|
2914
2908
|
/* TODO: rounding */
|
|
2915
2909
|
return check_exception(copy);
|
|
2916
2910
|
}
|
|
@@ -3568,7 +3562,6 @@ Init_bigdecimal(void)
|
|
|
3568
3562
|
rb_define_const(rb_cBigDecimal, "NAN", BIGDECIMAL_LITERAL(NAN, NaN));
|
|
3569
3563
|
|
|
3570
3564
|
/* instance methods */
|
|
3571
|
-
rb_define_method(rb_cBigDecimal, "precs", BigDecimal_prec, 0);
|
|
3572
3565
|
rb_define_method(rb_cBigDecimal, "precision", BigDecimal_precision, 0);
|
|
3573
3566
|
rb_define_method(rb_cBigDecimal, "scale", BigDecimal_scale, 0);
|
|
3574
3567
|
rb_define_method(rb_cBigDecimal, "precision_scale", BigDecimal_precision_scale, 0);
|
|
@@ -6141,7 +6134,7 @@ VpFrac(Real *y, Real *x)
|
|
|
6141
6134
|
size_t my, ind_y, ind_x;
|
|
6142
6135
|
|
|
6143
6136
|
if (!VpHasVal(x)) {
|
|
6144
|
-
VpAsgn(y, x,
|
|
6137
|
+
VpAsgn(y, x, 10);
|
|
6145
6138
|
goto Exit;
|
|
6146
6139
|
}
|
|
6147
6140
|
|
|
@@ -6150,7 +6143,7 @@ VpFrac(Real *y, Real *x)
|
|
|
6150
6143
|
goto Exit;
|
|
6151
6144
|
}
|
|
6152
6145
|
else if (x->exponent <= 0) {
|
|
6153
|
-
VpAsgn(y, x,
|
|
6146
|
+
VpAsgn(y, x, 10);
|
|
6154
6147
|
goto Exit;
|
|
6155
6148
|
}
|
|
6156
6149
|
|
data/lib/bigdecimal/jacobian.rb
CHANGED