bigdecimal 1.3.5 → 3.0.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 +6 -6
- data/ext/bigdecimal/bigdecimal.c +542 -249
- data/ext/bigdecimal/bigdecimal.h +5 -1
- data/ext/bigdecimal/extconf.rb +30 -6
- data/lib/bigdecimal.rb +1 -0
- data/lib/bigdecimal/jacobian.rb +3 -1
- data/lib/bigdecimal/util.rb +37 -7
- metadata +10 -25
- data/ext/bigdecimal/depend +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b3519c64aa42c80e19107fc6d5d78d81385d7d71b9c09abef67c4e4c6a0bcef
|
4
|
+
data.tar.gz: 4ab9cb50f0a24014262635c07ecb42e6891326b49de50f262550e22d00c586ed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e4aa6023012625b46f68a9e58d79a5ea0aa2c579ddb4245e0753a01118d62bd75fa5a708535346ab295619aa2ad9974a929189a83a00d56321c295a1ec8498c
|
7
|
+
data.tar.gz: 5717f808a7a56ae06b5060a3752fcaf3a9b47dca9dceb8e6822e603ec20f0296b711df04d1454a309ac6720d4af60e9b4e58f3477133f7a66e20eab75207a70e
|
data/bigdecimal.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
bigdecimal_version = '
|
3
|
+
bigdecimal_version = '3.0.0'
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = "bigdecimal"
|
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.summary = "Arbitrary-precision decimal floating-point number library."
|
12
12
|
s.description = "This library provides arbitrary-precision decimal floating-point number class."
|
13
13
|
s.homepage = "https://github.com/ruby/bigdecimal"
|
14
|
-
s.license = "
|
14
|
+
s.license = "Ruby"
|
15
15
|
|
16
16
|
s.require_paths = %w[lib]
|
17
17
|
s.extensions = %w[ext/bigdecimal/extconf.rb]
|
@@ -19,8 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
bigdecimal.gemspec
|
20
20
|
ext/bigdecimal/bigdecimal.c
|
21
21
|
ext/bigdecimal/bigdecimal.h
|
22
|
-
|
23
|
-
ext/bigdecimal/extconf.rb
|
22
|
+
lib/bigdecimal.rb
|
24
23
|
lib/bigdecimal/jacobian.rb
|
25
24
|
lib/bigdecimal/ludcmp.rb
|
26
25
|
lib/bigdecimal/math.rb
|
@@ -31,9 +30,10 @@ Gem::Specification.new do |s|
|
|
31
30
|
sample/pi.rb
|
32
31
|
]
|
33
32
|
|
34
|
-
s.
|
33
|
+
s.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
|
34
|
+
|
35
|
+
s.add_development_dependency "rake", ">= 12.3.3"
|
35
36
|
s.add_development_dependency "rake-compiler", ">= 0.9"
|
36
|
-
s.add_development_dependency "rake-compiler-dock", ">= 0.6.1"
|
37
37
|
s.add_development_dependency "minitest", "< 5.0.0"
|
38
38
|
s.add_development_dependency "pry"
|
39
39
|
end
|
data/ext/bigdecimal/bigdecimal.c
CHANGED
@@ -14,6 +14,7 @@
|
|
14
14
|
#include "ruby/util.h"
|
15
15
|
|
16
16
|
#ifndef BIGDECIMAL_DEBUG
|
17
|
+
# undef NDEBUG
|
17
18
|
# define NDEBUG
|
18
19
|
#endif
|
19
20
|
#include <assert.h>
|
@@ -24,7 +25,6 @@
|
|
24
25
|
#include <string.h>
|
25
26
|
#include <errno.h>
|
26
27
|
#include <math.h>
|
27
|
-
#include "math.h"
|
28
28
|
|
29
29
|
#ifdef HAVE_IEEEFP_H
|
30
30
|
#include <ieeefp.h>
|
@@ -77,7 +77,7 @@ static ID id_half;
|
|
77
77
|
#define BASE1 (BASE/10)
|
78
78
|
|
79
79
|
#ifndef DBLE_FIG
|
80
|
-
#define DBLE_FIG (
|
80
|
+
#define DBLE_FIG rmpd_double_figures() /* figure of double */
|
81
81
|
#endif
|
82
82
|
|
83
83
|
#ifndef RRATIONAL_ZERO_P
|
@@ -127,6 +127,30 @@ rb_rational_den(VALUE rat)
|
|
127
127
|
}
|
128
128
|
#endif
|
129
129
|
|
130
|
+
#ifndef HAVE_RB_COMPLEX_REAL
|
131
|
+
static inline VALUE
|
132
|
+
rb_complex_real(VALUE cmp)
|
133
|
+
{
|
134
|
+
#ifdef HAVE_TYPE_STRUCT_RCOMPLEX
|
135
|
+
return RCOMPLEX(cmp)->real;
|
136
|
+
#else
|
137
|
+
return rb_funcall(cmp, rb_intern("real"), 0);
|
138
|
+
#endif
|
139
|
+
}
|
140
|
+
#endif
|
141
|
+
|
142
|
+
#ifndef HAVE_RB_COMPLEX_IMAG
|
143
|
+
static inline VALUE
|
144
|
+
rb_complex_imag(VALUE cmp)
|
145
|
+
{
|
146
|
+
#ifdef HAVE_TYPE_STRUCT_RCOMPLEX
|
147
|
+
return RCOMPLEX(cmp)->imag;
|
148
|
+
#else
|
149
|
+
return rb_funcall(cmp, rb_intern("imag"), 0);
|
150
|
+
#endif
|
151
|
+
}
|
152
|
+
#endif
|
153
|
+
|
130
154
|
#define BIGDECIMAL_POSITIVE_P(bd) ((bd)->sign > 0)
|
131
155
|
#define BIGDECIMAL_NEGATIVE_P(bd) ((bd)->sign < 0)
|
132
156
|
|
@@ -135,24 +159,6 @@ rb_rational_den(VALUE rat)
|
|
135
159
|
*/
|
136
160
|
#define DoSomeOne(x,y,f) rb_num_coerce_bin(x,y,f)
|
137
161
|
|
138
|
-
/*
|
139
|
-
* Returns the BigDecimal version number.
|
140
|
-
*/
|
141
|
-
static VALUE
|
142
|
-
BigDecimal_version(VALUE self)
|
143
|
-
{
|
144
|
-
/*
|
145
|
-
* 1.0.0: Ruby 1.8.0
|
146
|
-
* 1.0.1: Ruby 1.8.1
|
147
|
-
* 1.1.0: Ruby 1.9.3
|
148
|
-
*/
|
149
|
-
#ifndef RUBY_BIGDECIMAL_VERSION
|
150
|
-
# error RUBY_BIGDECIMAL_VERSION is not defined
|
151
|
-
#endif
|
152
|
-
rb_warning("BigDecimal.ver is deprecated; use BigDecimal::VERSION instead.");
|
153
|
-
return rb_str_new2(RUBY_BIGDECIMAL_VERSION);
|
154
|
-
}
|
155
|
-
|
156
162
|
/*
|
157
163
|
* VP routines used in BigDecimal part
|
158
164
|
*/
|
@@ -183,11 +189,16 @@ BigDecimal_memsize(const void *ptr)
|
|
183
189
|
return (sizeof(*pv) + pv->MaxPrec * sizeof(BDIGIT));
|
184
190
|
}
|
185
191
|
|
192
|
+
#ifndef HAVE_RB_EXT_RACTOR_SAFE
|
193
|
+
# undef RUBY_TYPED_FROZEN_SHAREABLE
|
194
|
+
# define RUBY_TYPED_FROZEN_SHAREABLE 0
|
195
|
+
#endif
|
196
|
+
|
186
197
|
static const rb_data_type_t BigDecimal_data_type = {
|
187
198
|
"BigDecimal",
|
188
199
|
{ 0, BigDecimal_delete, BigDecimal_memsize, },
|
189
200
|
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
|
190
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
201
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE
|
191
202
|
#endif
|
192
203
|
};
|
193
204
|
|
@@ -246,7 +257,7 @@ again:
|
|
246
257
|
switch(TYPE(v)) {
|
247
258
|
case T_FLOAT:
|
248
259
|
if (prec < 0) goto unable_to_coerce_without_prec;
|
249
|
-
if (prec >
|
260
|
+
if (prec > (long)DBLE_FIG) goto SomeOneMayDoIt;
|
250
261
|
d = RFLOAT_VALUE(v);
|
251
262
|
if (!isfinite(d)) {
|
252
263
|
pv = VpCreateRbObject(1, NULL);
|
@@ -294,7 +305,6 @@ again:
|
|
294
305
|
#ifdef ENABLE_NUMERIC_STRING
|
295
306
|
case T_STRING:
|
296
307
|
StringValueCStr(v);
|
297
|
-
rb_check_safe_obj(v);
|
298
308
|
return VpCreateRbObject(RSTRING_LEN(v) + VpBaseFig() + 1,
|
299
309
|
RSTRING_PTR(v));
|
300
310
|
#endif /* ENABLE_NUMERIC_STRING */
|
@@ -345,11 +355,13 @@ BigDecimal_double_fig(VALUE self)
|
|
345
355
|
/* call-seq:
|
346
356
|
* big_decimal.precs -> array
|
347
357
|
*
|
348
|
-
* Returns an Array of two Integer values
|
358
|
+
* Returns an Array of two Integer values that represent platform-dependent
|
359
|
+
* internal storage properties.
|
349
360
|
*
|
350
|
-
*
|
351
|
-
*
|
352
|
-
*
|
361
|
+
* This method is deprecated and will be removed in the future.
|
362
|
+
* Instead, use BigDecimal#n_significant_digits for obtaining the number of
|
363
|
+
* significant digits in scientific notation, and BigDecimal#precision for
|
364
|
+
* obtaining the number of digits in decimal notation.
|
353
365
|
*
|
354
366
|
* BigDecimal('5').precs #=> [9, 18]
|
355
367
|
*/
|
@@ -361,12 +373,109 @@ BigDecimal_prec(VALUE self)
|
|
361
373
|
Real *p;
|
362
374
|
VALUE obj;
|
363
375
|
|
376
|
+
rb_category_warn(RB_WARN_CATEGORY_DEPRECATED,
|
377
|
+
"BigDecimal#precs is deprecated and will be removed in the future; "
|
378
|
+
"use BigDecimal#precision instead.");
|
379
|
+
|
364
380
|
GUARD_OBJ(p, GetVpValue(self, 1));
|
365
|
-
obj = rb_assoc_new(
|
366
|
-
|
381
|
+
obj = rb_assoc_new(SIZET2NUM(p->Prec*VpBaseFig()),
|
382
|
+
SIZET2NUM(p->MaxPrec*VpBaseFig()));
|
367
383
|
return obj;
|
368
384
|
}
|
369
385
|
|
386
|
+
/*
|
387
|
+
* call-seq:
|
388
|
+
* big_decimal.precision -> intreger
|
389
|
+
*
|
390
|
+
* Returns the number of decimal digits in this number.
|
391
|
+
*
|
392
|
+
* Example:
|
393
|
+
*
|
394
|
+
* BigDecimal("0").precision # => 0
|
395
|
+
* BigDecimal("1").precision # => 1
|
396
|
+
* BigDecimal("-1e20").precision # => 21
|
397
|
+
* BigDecimal("1e-20").precision # => 20
|
398
|
+
* BigDecimal("Infinity").precision # => 0
|
399
|
+
* BigDecimal("-Infinity").precision # => 0
|
400
|
+
* BigDecimal("NaN").precision # => 0
|
401
|
+
*/
|
402
|
+
static VALUE
|
403
|
+
BigDecimal_precision(VALUE self)
|
404
|
+
{
|
405
|
+
ENTER(1);
|
406
|
+
|
407
|
+
Real *p;
|
408
|
+
GUARD_OBJ(p, GetVpValue(self, 1));
|
409
|
+
|
410
|
+
/*
|
411
|
+
* The most significant digit is frac[0], and the least significant digit is frac[Prec-1].
|
412
|
+
* When the exponent is zero, the decimal point is located just before frac[0].
|
413
|
+
* When the exponent is negative, the decimal point moves to leftward.
|
414
|
+
* Conversely, when the exponent is positive, the decimal point moves to rightward.
|
415
|
+
*
|
416
|
+
* | frac[0] frac[1] frac[2] . frac[3] frac[4] ... frac[Prec-1]
|
417
|
+
* |------------------------> exponent == 3
|
418
|
+
*/
|
419
|
+
|
420
|
+
ssize_t ex = p->exponent;
|
421
|
+
ssize_t precision;
|
422
|
+
if (ex < 0) {
|
423
|
+
precision = (-ex + 1) * BASE_FIG; /* 1 is for p->frac[0] */
|
424
|
+
ex = 0;
|
425
|
+
}
|
426
|
+
else if (p->Prec > 0) {
|
427
|
+
BDIGIT x = p->frac[0];
|
428
|
+
for (precision = 0; x > 0; x /= 10) {
|
429
|
+
++precision;
|
430
|
+
}
|
431
|
+
}
|
432
|
+
|
433
|
+
if (ex > (ssize_t)p->Prec) {
|
434
|
+
precision += (ex - 1) * BASE_FIG;
|
435
|
+
}
|
436
|
+
else if (p->Prec > 0) {
|
437
|
+
ssize_t n = (ssize_t)p->Prec - 1;
|
438
|
+
while (n > 0 && p->frac[n] == 0) --n;
|
439
|
+
|
440
|
+
precision += n * BASE_FIG;
|
441
|
+
|
442
|
+
if (ex < (ssize_t)p->Prec) {
|
443
|
+
BDIGIT x = p->frac[n];
|
444
|
+
for (; x > 0 && x % 10 == 0; x /= 10) {
|
445
|
+
--precision;
|
446
|
+
}
|
447
|
+
}
|
448
|
+
}
|
449
|
+
|
450
|
+
return SSIZET2NUM(precision);
|
451
|
+
}
|
452
|
+
|
453
|
+
static VALUE
|
454
|
+
BigDecimal_n_significant_digits(VALUE self)
|
455
|
+
{
|
456
|
+
ENTER(1);
|
457
|
+
|
458
|
+
Real *p;
|
459
|
+
GUARD_OBJ(p, GetVpValue(self, 1));
|
460
|
+
|
461
|
+
ssize_t n = p->Prec;
|
462
|
+
while (n > 0 && p->frac[n-1] == 0) --n;
|
463
|
+
if (n <= 0) {
|
464
|
+
return INT2FIX(0);
|
465
|
+
}
|
466
|
+
|
467
|
+
int nlz, ntz;
|
468
|
+
|
469
|
+
BDIGIT x = p->frac[0];
|
470
|
+
for (nlz = BASE_FIG; x > 0; x /= 10) --nlz;
|
471
|
+
|
472
|
+
x = p->frac[n-1];
|
473
|
+
for (ntz = 0; x > 0 && x % 10 == 0; x /= 10) ++ntz;
|
474
|
+
|
475
|
+
ssize_t n_digits = BASE_FIG * n - nlz - ntz;
|
476
|
+
return SSIZET2NUM(n_digits);
|
477
|
+
}
|
478
|
+
|
370
479
|
/*
|
371
480
|
* call-seq: hash
|
372
481
|
*
|
@@ -436,7 +545,6 @@ BigDecimal_load(VALUE self, VALUE str)
|
|
436
545
|
unsigned long m=0;
|
437
546
|
|
438
547
|
pch = (unsigned char *)StringValueCStr(str);
|
439
|
-
rb_check_safe_obj(str);
|
440
548
|
/* First get max prec */
|
441
549
|
while((*pch) != (unsigned char)'\0' && (ch = *pch++) != (unsigned char)':') {
|
442
550
|
if(!ISDIGIT(ch)) {
|
@@ -664,9 +772,10 @@ VP_EXPORT Real *
|
|
664
772
|
VpNewRbClass(size_t mx, const char *str, VALUE klass)
|
665
773
|
{
|
666
774
|
VALUE obj = TypedData_Wrap_Struct(klass, &BigDecimal_data_type, 0);
|
667
|
-
Real *pv = VpAlloc(mx,str);
|
775
|
+
Real *pv = VpAlloc(mx, str, 1, 1);
|
668
776
|
RTYPEDDATA_DATA(obj) = pv;
|
669
777
|
pv->obj = obj;
|
778
|
+
RB_OBJ_FREEZE(obj);
|
670
779
|
return pv;
|
671
780
|
}
|
672
781
|
|
@@ -894,7 +1003,7 @@ BigDecimal_coerce(VALUE self, VALUE other)
|
|
894
1003
|
Real *b;
|
895
1004
|
|
896
1005
|
if (RB_TYPE_P(other, T_FLOAT)) {
|
897
|
-
GUARD_OBJ(b, GetVpValueWithPrec(other,
|
1006
|
+
GUARD_OBJ(b, GetVpValueWithPrec(other, DBLE_FIG, 1));
|
898
1007
|
obj = rb_assoc_new(ToValue(b), self);
|
899
1008
|
}
|
900
1009
|
else {
|
@@ -952,7 +1061,7 @@ BigDecimal_add(VALUE self, VALUE r)
|
|
952
1061
|
|
953
1062
|
GUARD_OBJ(a, GetVpValue(self, 1));
|
954
1063
|
if (RB_TYPE_P(r, T_FLOAT)) {
|
955
|
-
b = GetVpValueWithPrec(r,
|
1064
|
+
b = GetVpValueWithPrec(r, DBLE_FIG, 1);
|
956
1065
|
}
|
957
1066
|
else if (RB_TYPE_P(r, T_RATIONAL)) {
|
958
1067
|
b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
|
@@ -1010,7 +1119,7 @@ BigDecimal_sub(VALUE self, VALUE r)
|
|
1010
1119
|
|
1011
1120
|
GUARD_OBJ(a, GetVpValue(self,1));
|
1012
1121
|
if (RB_TYPE_P(r, T_FLOAT)) {
|
1013
|
-
b = GetVpValueWithPrec(r,
|
1122
|
+
b = GetVpValueWithPrec(r, DBLE_FIG, 1);
|
1014
1123
|
}
|
1015
1124
|
else if (RB_TYPE_P(r, T_RATIONAL)) {
|
1016
1125
|
b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
|
@@ -1060,7 +1169,7 @@ BigDecimalCmp(VALUE self, VALUE r,char op)
|
|
1060
1169
|
break;
|
1061
1170
|
|
1062
1171
|
case T_FLOAT:
|
1063
|
-
GUARD_OBJ(b, GetVpValueWithPrec(r,
|
1172
|
+
GUARD_OBJ(b, GetVpValueWithPrec(r, DBLE_FIG, 0));
|
1064
1173
|
break;
|
1065
1174
|
|
1066
1175
|
case T_RATIONAL:
|
@@ -1273,7 +1382,7 @@ BigDecimal_mult(VALUE self, VALUE r)
|
|
1273
1382
|
|
1274
1383
|
GUARD_OBJ(a, GetVpValue(self, 1));
|
1275
1384
|
if (RB_TYPE_P(r, T_FLOAT)) {
|
1276
|
-
|
1385
|
+
b = GetVpValueWithPrec(r, DBLE_FIG, 1);
|
1277
1386
|
}
|
1278
1387
|
else if (RB_TYPE_P(r, T_RATIONAL)) {
|
1279
1388
|
b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
|
@@ -1301,7 +1410,7 @@ BigDecimal_divide(Real **c, Real **res, Real **div, VALUE self, VALUE r)
|
|
1301
1410
|
|
1302
1411
|
GUARD_OBJ(a, GetVpValue(self, 1));
|
1303
1412
|
if (RB_TYPE_P(r, T_FLOAT)) {
|
1304
|
-
|
1413
|
+
b = GetVpValueWithPrec(r, DBLE_FIG, 1);
|
1305
1414
|
}
|
1306
1415
|
else if (RB_TYPE_P(r, T_RATIONAL)) {
|
1307
1416
|
b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
|
@@ -1367,7 +1476,7 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod)
|
|
1367
1476
|
|
1368
1477
|
GUARD_OBJ(a, GetVpValue(self, 1));
|
1369
1478
|
if (RB_TYPE_P(r, T_FLOAT)) {
|
1370
|
-
b = GetVpValueWithPrec(r,
|
1479
|
+
b = GetVpValueWithPrec(r, DBLE_FIG, 1);
|
1371
1480
|
}
|
1372
1481
|
else if (RB_TYPE_P(r, T_RATIONAL)) {
|
1373
1482
|
b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
|
@@ -1468,7 +1577,7 @@ BigDecimal_divremain(VALUE self, VALUE r, Real **dv, Real **rv)
|
|
1468
1577
|
|
1469
1578
|
GUARD_OBJ(a, GetVpValue(self, 1));
|
1470
1579
|
if (RB_TYPE_P(r, T_FLOAT)) {
|
1471
|
-
b = GetVpValueWithPrec(r,
|
1580
|
+
b = GetVpValueWithPrec(r, DBLE_FIG, 1);
|
1472
1581
|
}
|
1473
1582
|
else if (RB_TYPE_P(r, T_RATIONAL)) {
|
1474
1583
|
b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
|
@@ -1773,20 +1882,23 @@ BigDecimal_fix(VALUE self)
|
|
1773
1882
|
* round(n, mode)
|
1774
1883
|
*
|
1775
1884
|
* Round to the nearest integer (by default), returning the result as a
|
1776
|
-
* BigDecimal.
|
1885
|
+
* BigDecimal if n is specified, or as an Integer if it isn't.
|
1777
1886
|
*
|
1778
1887
|
* BigDecimal('3.14159').round #=> 3
|
1779
1888
|
* BigDecimal('8.7').round #=> 9
|
1780
1889
|
* BigDecimal('-9.9').round #=> -10
|
1781
1890
|
*
|
1891
|
+
* BigDecimal('3.14159').round(2).class.name #=> "BigDecimal"
|
1892
|
+
* BigDecimal('3.14159').round.class.name #=> "Integer"
|
1893
|
+
*
|
1782
1894
|
* If n is specified and positive, the fractional part of the result has no
|
1783
1895
|
* more than that many digits.
|
1784
1896
|
*
|
1785
1897
|
* If n is specified and negative, at least that many digits to the left of the
|
1786
|
-
* decimal point will be 0 in the result.
|
1898
|
+
* decimal point will be 0 in the result, and return value will be an Integer.
|
1787
1899
|
*
|
1788
1900
|
* BigDecimal('3.14159').round(3) #=> 3.142
|
1789
|
-
* BigDecimal('13345.234').round(-2) #=> 13300
|
1901
|
+
* BigDecimal('13345.234').round(-2) #=> 13300
|
1790
1902
|
*
|
1791
1903
|
* The value of the optional mode argument can be used to determine how
|
1792
1904
|
* rounding is performed; see BigDecimal.mode.
|
@@ -1799,6 +1911,7 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
|
|
1799
1911
|
int iLoc = 0;
|
1800
1912
|
VALUE vLoc;
|
1801
1913
|
VALUE vRound;
|
1914
|
+
int round_to_int = 0;
|
1802
1915
|
size_t mx, pl;
|
1803
1916
|
|
1804
1917
|
unsigned short sw = VpGetRoundMode();
|
@@ -1806,6 +1919,7 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
|
|
1806
1919
|
switch (rb_scan_args(argc, argv, "02", &vLoc, &vRound)) {
|
1807
1920
|
case 0:
|
1808
1921
|
iLoc = 0;
|
1922
|
+
round_to_int = 1;
|
1809
1923
|
break;
|
1810
1924
|
case 1:
|
1811
1925
|
if (RB_TYPE_P(vLoc, T_HASH)) {
|
@@ -1813,6 +1927,7 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
|
|
1813
1927
|
}
|
1814
1928
|
else {
|
1815
1929
|
iLoc = NUM2INT(vLoc);
|
1930
|
+
if (iLoc < 1) round_to_int = 1;
|
1816
1931
|
}
|
1817
1932
|
break;
|
1818
1933
|
case 2:
|
@@ -1834,7 +1949,7 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
|
|
1834
1949
|
GUARD_OBJ(c, VpCreateRbObject(mx, "0"));
|
1835
1950
|
VpSetPrecLimit(pl);
|
1836
1951
|
VpActiveRound(c, a, sw, iLoc);
|
1837
|
-
if (
|
1952
|
+
if (round_to_int) {
|
1838
1953
|
return BigDecimal_to_i(ToValue(c));
|
1839
1954
|
}
|
1840
1955
|
return ToValue(c);
|
@@ -2044,7 +2159,6 @@ BigDecimal_to_s(int argc, VALUE *argv, VALUE self)
|
|
2044
2159
|
if (rb_scan_args(argc, argv, "01", &f) == 1) {
|
2045
2160
|
if (RB_TYPE_P(f, T_STRING)) {
|
2046
2161
|
psz = StringValueCStr(f);
|
2047
|
-
rb_check_safe_obj(f);
|
2048
2162
|
if (*psz == ' ') {
|
2049
2163
|
fPlus = 1;
|
2050
2164
|
psz++;
|
@@ -2084,7 +2198,7 @@ BigDecimal_to_s(int argc, VALUE *argv, VALUE self)
|
|
2084
2198
|
nc += (nc + mc - 1) / mc + 1;
|
2085
2199
|
}
|
2086
2200
|
|
2087
|
-
str =
|
2201
|
+
str = rb_usascii_str_new(0, nc);
|
2088
2202
|
psz = RSTRING_PTR(str);
|
2089
2203
|
|
2090
2204
|
if (fmt) {
|
@@ -2149,7 +2263,7 @@ BigDecimal_split(VALUE self)
|
|
2149
2263
|
rb_ary_push(obj, str);
|
2150
2264
|
rb_str_resize(str, strlen(psz1));
|
2151
2265
|
rb_ary_push(obj, INT2FIX(10));
|
2152
|
-
rb_ary_push(obj,
|
2266
|
+
rb_ary_push(obj, SSIZET2NUM(e));
|
2153
2267
|
return obj;
|
2154
2268
|
}
|
2155
2269
|
|
@@ -2162,18 +2276,13 @@ static VALUE
|
|
2162
2276
|
BigDecimal_exponent(VALUE self)
|
2163
2277
|
{
|
2164
2278
|
ssize_t e = VpExponent10(GetVpValue(self, 1));
|
2165
|
-
return
|
2279
|
+
return SSIZET2NUM(e);
|
2166
2280
|
}
|
2167
2281
|
|
2168
|
-
/* Returns
|
2169
|
-
* values in angle brackets with a leading #:
|
2282
|
+
/* Returns a string representation of self.
|
2170
2283
|
*
|
2171
2284
|
* BigDecimal("1234.5678").inspect
|
2172
2285
|
* #=> "0.12345678e4"
|
2173
|
-
*
|
2174
|
-
* The first part is the address, the second is the value as a string, and
|
2175
|
-
* the final part ss(mm) is the current number of significant digits and the
|
2176
|
-
* maximum number of significant digits, respectively.
|
2177
2286
|
*/
|
2178
2287
|
static VALUE
|
2179
2288
|
BigDecimal_inspect(VALUE self)
|
@@ -2335,7 +2444,7 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
|
|
2335
2444
|
n = NIL_P(prec) ? (ssize_t)(x->Prec*VpBaseFig()) : NUM2SSIZET(prec);
|
2336
2445
|
|
2337
2446
|
if (VpIsNaN(x)) {
|
2338
|
-
y = VpCreateRbObject(n, "0
|
2447
|
+
y = VpCreateRbObject(n, "0");
|
2339
2448
|
RB_GC_GUARD(y->obj);
|
2340
2449
|
VpSetNaN(y);
|
2341
2450
|
return ToValue(y);
|
@@ -2360,7 +2469,10 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
|
|
2360
2469
|
}
|
2361
2470
|
goto retry;
|
2362
2471
|
}
|
2363
|
-
|
2472
|
+
if (NIL_P(prec)) {
|
2473
|
+
n += DBLE_FIG;
|
2474
|
+
}
|
2475
|
+
exp = GetVpValueWithPrec(vexp, DBLE_FIG, 1);
|
2364
2476
|
break;
|
2365
2477
|
|
2366
2478
|
case T_RATIONAL:
|
@@ -2375,6 +2487,9 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
|
|
2375
2487
|
goto retry;
|
2376
2488
|
}
|
2377
2489
|
exp = GetVpValueWithPrec(vexp, n, 1);
|
2490
|
+
if (NIL_P(prec)) {
|
2491
|
+
n += n;
|
2492
|
+
}
|
2378
2493
|
break;
|
2379
2494
|
|
2380
2495
|
case T_DATA:
|
@@ -2385,6 +2500,10 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
|
|
2385
2500
|
vexp = BigDecimal_to_i(vexp);
|
2386
2501
|
goto retry;
|
2387
2502
|
}
|
2503
|
+
if (NIL_P(prec)) {
|
2504
|
+
GUARD_OBJ(y, GetVpValue(vexp, 1));
|
2505
|
+
n += y->Prec*VpBaseFig();
|
2506
|
+
}
|
2388
2507
|
exp = DATA_PTR(vexp);
|
2389
2508
|
break;
|
2390
2509
|
}
|
@@ -2459,7 +2578,7 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
|
|
2459
2578
|
}
|
2460
2579
|
}
|
2461
2580
|
else {
|
2462
|
-
y = VpCreateRbObject(n, "0
|
2581
|
+
y = VpCreateRbObject(n, "0");
|
2463
2582
|
if (BIGDECIMAL_NEGATIVE_P(x)) {
|
2464
2583
|
if (is_integer(vexp)) {
|
2465
2584
|
if (is_even(vexp)) {
|
@@ -2492,7 +2611,7 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
|
|
2492
2611
|
}
|
2493
2612
|
else if (RTEST(rb_funcall(abs_value, '<', 1, INT2FIX(1)))) {
|
2494
2613
|
if (is_negative(vexp)) {
|
2495
|
-
y = VpCreateRbObject(n, "0
|
2614
|
+
y = VpCreateRbObject(n, "0");
|
2496
2615
|
if (is_even(vexp)) {
|
2497
2616
|
VpSetInf(y, VpGetSign(x));
|
2498
2617
|
}
|
@@ -2510,7 +2629,7 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
|
|
2510
2629
|
}
|
2511
2630
|
else {
|
2512
2631
|
if (is_positive(vexp)) {
|
2513
|
-
y = VpCreateRbObject(n, "0
|
2632
|
+
y = VpCreateRbObject(n, "0");
|
2514
2633
|
if (is_even(vexp)) {
|
2515
2634
|
VpSetInf(y, VpGetSign(x));
|
2516
2635
|
}
|
@@ -2560,72 +2679,6 @@ BigDecimal_power_op(VALUE self, VALUE exp)
|
|
2560
2679
|
return BigDecimal_power(1, &exp, self);
|
2561
2680
|
}
|
2562
2681
|
|
2563
|
-
static VALUE
|
2564
|
-
BigDecimal_s_allocate(VALUE klass)
|
2565
|
-
{
|
2566
|
-
return VpNewRbClass(0, NULL, klass)->obj;
|
2567
|
-
}
|
2568
|
-
|
2569
|
-
static Real *BigDecimal_new(int argc, VALUE *argv);
|
2570
|
-
|
2571
|
-
/* call-seq:
|
2572
|
-
* new(initial, digits)
|
2573
|
-
*
|
2574
|
-
* Create a new BigDecimal object.
|
2575
|
-
*
|
2576
|
-
* initial:: The initial value, as an Integer, a Float, a Rational,
|
2577
|
-
* a BigDecimal, or a String.
|
2578
|
-
*
|
2579
|
-
* If it is a String, spaces are ignored and unrecognized characters
|
2580
|
-
* terminate the value.
|
2581
|
-
*
|
2582
|
-
* digits:: The number of significant digits, as an Integer. If omitted or 0,
|
2583
|
-
* the number of significant digits is determined from the initial
|
2584
|
-
* value.
|
2585
|
-
*
|
2586
|
-
* The actual number of significant digits used in computation is usually
|
2587
|
-
* larger than the specified number.
|
2588
|
-
*
|
2589
|
-
* ==== Exceptions
|
2590
|
-
*
|
2591
|
-
* TypeError:: If the +initial+ type is neither Integer, Float,
|
2592
|
-
* Rational, nor BigDecimal, this exception is raised.
|
2593
|
-
*
|
2594
|
-
* TypeError:: If the +digits+ is not an Integer, this exception is raised.
|
2595
|
-
*
|
2596
|
-
* ArgumentError:: If +initial+ is a Float, and the +digits+ is larger than
|
2597
|
-
* Float::DIG + 1, this exception is raised.
|
2598
|
-
*
|
2599
|
-
* ArgumentError:: If the +initial+ is a Float or Rational, and the +digits+
|
2600
|
-
* value is omitted, this exception is raised.
|
2601
|
-
*/
|
2602
|
-
static VALUE
|
2603
|
-
BigDecimal_s_new(int argc, VALUE *argv, VALUE self)
|
2604
|
-
{
|
2605
|
-
rb_warning("BigDecimal.new is deprecated; use Kernel.BigDecimal method instead.");
|
2606
|
-
return rb_call_super(argc, argv);
|
2607
|
-
}
|
2608
|
-
|
2609
|
-
static VALUE
|
2610
|
-
BigDecimal_initialize(int argc, VALUE *argv, VALUE self)
|
2611
|
-
{
|
2612
|
-
ENTER(1);
|
2613
|
-
Real *pv = rb_check_typeddata(self, &BigDecimal_data_type);
|
2614
|
-
Real *x;
|
2615
|
-
|
2616
|
-
GUARD_OBJ(x, BigDecimal_new(argc, argv));
|
2617
|
-
if (ToValue(x)) {
|
2618
|
-
pv = VpCopy(pv, x);
|
2619
|
-
}
|
2620
|
-
else {
|
2621
|
-
VpFree(pv);
|
2622
|
-
pv = x;
|
2623
|
-
}
|
2624
|
-
DATA_PTR(self) = pv;
|
2625
|
-
pv->obj = self;
|
2626
|
-
return self;
|
2627
|
-
}
|
2628
|
-
|
2629
2682
|
/* :nodoc:
|
2630
2683
|
*
|
2631
2684
|
* private method for dup and clone the provided BigDecimal +other+
|
@@ -2648,21 +2701,75 @@ BigDecimal_clone(VALUE self)
|
|
2648
2701
|
return self;
|
2649
2702
|
}
|
2650
2703
|
|
2704
|
+
#ifdef HAVE_RB_OPTS_EXCEPTION_P
|
2705
|
+
int rb_opts_exception_p(VALUE opts, int default_value);
|
2706
|
+
#define opts_exception_p(opts) rb_opts_exception_p((opts), 1)
|
2707
|
+
#else
|
2708
|
+
static int
|
2709
|
+
opts_exception_p(VALUE opts)
|
2710
|
+
{
|
2711
|
+
static ID kwds[1];
|
2712
|
+
VALUE exception;
|
2713
|
+
if (!kwds[0]) {
|
2714
|
+
kwds[0] = rb_intern_const("exception");
|
2715
|
+
}
|
2716
|
+
if (!rb_get_kwargs(opts, kwds, 0, 1, &exception)) return 1;
|
2717
|
+
switch (exception) {
|
2718
|
+
case Qtrue: case Qfalse:
|
2719
|
+
break;
|
2720
|
+
default:
|
2721
|
+
rb_raise(rb_eArgError, "true or false is expected as exception: %+"PRIsVALUE,
|
2722
|
+
exception);
|
2723
|
+
}
|
2724
|
+
return exception != Qfalse;
|
2725
|
+
}
|
2726
|
+
#endif
|
2727
|
+
|
2651
2728
|
static Real *
|
2652
|
-
|
2729
|
+
VpNewVarArg(int argc, VALUE *argv)
|
2653
2730
|
{
|
2654
2731
|
size_t mf;
|
2732
|
+
VALUE opts = Qnil;
|
2655
2733
|
VALUE nFig;
|
2656
2734
|
VALUE iniValue;
|
2657
2735
|
double d;
|
2736
|
+
int exc;
|
2658
2737
|
|
2659
|
-
|
2738
|
+
argc = rb_scan_args(argc, argv, "11:", &iniValue, &nFig, &opts);
|
2739
|
+
exc = opts_exception_p(opts);
|
2740
|
+
|
2741
|
+
if (argc == 1) {
|
2660
2742
|
mf = 0;
|
2661
2743
|
}
|
2662
2744
|
else {
|
2663
|
-
|
2745
|
+
/* expand GetPrecisionInt for exception suppression */
|
2746
|
+
ssize_t n = NUM2INT(nFig);
|
2747
|
+
if (n < 0) {
|
2748
|
+
if (!exc) {
|
2749
|
+
return NULL;
|
2750
|
+
}
|
2751
|
+
rb_raise(rb_eArgError, "negative precision");
|
2752
|
+
}
|
2753
|
+
mf = (size_t)n;
|
2754
|
+
}
|
2755
|
+
|
2756
|
+
if (SPECIAL_CONST_P(iniValue)) {
|
2757
|
+
switch (iniValue) {
|
2758
|
+
case Qnil:
|
2759
|
+
if (!exc) return NULL;
|
2760
|
+
rb_raise(rb_eTypeError, "can't convert nil into BigDecimal");
|
2761
|
+
case Qtrue:
|
2762
|
+
if (!exc) return NULL;
|
2763
|
+
rb_raise(rb_eTypeError, "can't convert true into BigDecimal");
|
2764
|
+
case Qfalse:
|
2765
|
+
if (!exc) return NULL;
|
2766
|
+
rb_raise(rb_eTypeError, "can't convert false into BigDecimal");
|
2767
|
+
default:
|
2768
|
+
break;
|
2769
|
+
}
|
2664
2770
|
}
|
2665
2771
|
|
2772
|
+
retry:
|
2666
2773
|
switch (TYPE(iniValue)) {
|
2667
2774
|
case T_DATA:
|
2668
2775
|
if (is_kind_of_BigDecimal(iniValue)) {
|
@@ -2682,42 +2789,120 @@ BigDecimal_new(int argc, VALUE *argv)
|
|
2682
2789
|
VpDtoV(pv, d);
|
2683
2790
|
return pv;
|
2684
2791
|
}
|
2685
|
-
if (mf >
|
2792
|
+
if (mf > DBLE_FIG) {
|
2793
|
+
if (!exc) {
|
2794
|
+
return NULL;
|
2795
|
+
}
|
2686
2796
|
rb_raise(rb_eArgError, "precision too large.");
|
2687
2797
|
}
|
2688
2798
|
/* fall through */
|
2689
2799
|
case T_RATIONAL:
|
2690
2800
|
if (NIL_P(nFig)) {
|
2801
|
+
if (!exc) {
|
2802
|
+
return NULL;
|
2803
|
+
}
|
2691
2804
|
rb_raise(rb_eArgError,
|
2692
2805
|
"can't omit precision for a %"PRIsVALUE".",
|
2693
2806
|
RB_OBJ_CLASSNAME(iniValue));
|
2694
2807
|
}
|
2695
2808
|
return GetVpValueWithPrec(iniValue, mf, 1);
|
2696
2809
|
|
2810
|
+
case T_COMPLEX:
|
2811
|
+
{
|
2812
|
+
VALUE im;
|
2813
|
+
im = rb_complex_imag(iniValue);
|
2814
|
+
if (!is_zero(im)) {
|
2815
|
+
rb_raise(rb_eArgError,
|
2816
|
+
"Unable to make a BigDecimal from non-zero imaginary number");
|
2817
|
+
}
|
2818
|
+
iniValue = rb_complex_real(iniValue);
|
2819
|
+
goto retry;
|
2820
|
+
}
|
2821
|
+
|
2697
2822
|
case T_STRING:
|
2698
2823
|
/* fall through */
|
2699
2824
|
default:
|
2700
2825
|
break;
|
2701
2826
|
}
|
2827
|
+
/* TODO: support to_d */
|
2828
|
+
if (!exc) {
|
2829
|
+
iniValue = rb_check_convert_type(iniValue, T_STRING, "String", "to_str");
|
2830
|
+
if (NIL_P(iniValue)) return NULL;
|
2831
|
+
}
|
2702
2832
|
StringValueCStr(iniValue);
|
2703
|
-
return VpAlloc(mf, RSTRING_PTR(iniValue));
|
2833
|
+
return VpAlloc(mf, RSTRING_PTR(iniValue), 1, exc);
|
2704
2834
|
}
|
2705
2835
|
|
2706
|
-
/*
|
2836
|
+
/* call-seq:
|
2837
|
+
* BigDecimal(initial, digits, exception: true)
|
2838
|
+
*
|
2839
|
+
* Create a new BigDecimal object.
|
2840
|
+
*
|
2841
|
+
* initial:: The initial value, as an Integer, a Float, a Rational,
|
2842
|
+
* a BigDecimal, or a String.
|
2843
|
+
*
|
2844
|
+
* If it is a String, spaces are ignored and unrecognized characters
|
2845
|
+
* terminate the value.
|
2846
|
+
*
|
2847
|
+
* digits:: The number of significant digits, as an Integer. If omitted or 0,
|
2848
|
+
* the number of significant digits is determined from the initial
|
2849
|
+
* value.
|
2850
|
+
*
|
2851
|
+
* The actual number of significant digits used in computation is
|
2852
|
+
* usually larger than the specified number.
|
2853
|
+
*
|
2854
|
+
* exception:: Whether an exception should be raised on invalid arguments.
|
2855
|
+
* +true+ by default, if passed +false+, just returns +nil+
|
2856
|
+
* for invalid.
|
2857
|
+
*
|
2858
|
+
*
|
2859
|
+
* ==== Exceptions
|
2860
|
+
*
|
2861
|
+
* TypeError:: If the +initial+ type is neither Integer, Float,
|
2862
|
+
* Rational, nor BigDecimal, this exception is raised.
|
2863
|
+
*
|
2864
|
+
* TypeError:: If the +digits+ is not an Integer, this exception is raised.
|
2865
|
+
*
|
2866
|
+
* ArgumentError:: If +initial+ is a Float, and the +digits+ is larger than
|
2867
|
+
* Float::DIG + 1, this exception is raised.
|
2868
|
+
*
|
2869
|
+
* ArgumentError:: If the +initial+ is a Float or Rational, and the +digits+
|
2870
|
+
* value is omitted, this exception is raised.
|
2871
|
+
*/
|
2707
2872
|
static VALUE
|
2708
|
-
|
2873
|
+
f_BigDecimal(int argc, VALUE *argv, VALUE self)
|
2709
2874
|
{
|
2710
2875
|
ENTER(1);
|
2711
2876
|
Real *pv;
|
2712
2877
|
VALUE obj;
|
2713
2878
|
|
2879
|
+
if (argc > 0 && CLASS_OF(argv[0]) == rb_cBigDecimal) {
|
2880
|
+
if (argc == 1 || (argc == 2 && RB_TYPE_P(argv[1], T_HASH))) return argv[0];
|
2881
|
+
}
|
2714
2882
|
obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, 0);
|
2715
|
-
|
2883
|
+
pv = VpNewVarArg(argc, argv);
|
2884
|
+
if (pv == NULL) return Qnil;
|
2885
|
+
SAVE(pv);
|
2716
2886
|
if (ToValue(pv)) pv = VpCopy(NULL, pv);
|
2717
2887
|
RTYPEDDATA_DATA(obj) = pv;
|
2888
|
+
RB_OBJ_FREEZE(obj);
|
2718
2889
|
return pv->obj = obj;
|
2719
2890
|
}
|
2720
2891
|
|
2892
|
+
static VALUE
|
2893
|
+
BigDecimal_s_interpret_loosely(VALUE klass, VALUE str)
|
2894
|
+
{
|
2895
|
+
ENTER(1);
|
2896
|
+
char const *c_str;
|
2897
|
+
Real *pv;
|
2898
|
+
|
2899
|
+
c_str = StringValueCStr(str);
|
2900
|
+
GUARD_OBJ(pv, VpAlloc(0, c_str, 0, 1));
|
2901
|
+
pv->obj = TypedData_Wrap_Struct(klass, &BigDecimal_data_type, pv);
|
2902
|
+
RB_OBJ_FREEZE(pv->obj);
|
2903
|
+
return pv->obj;
|
2904
|
+
}
|
2905
|
+
|
2721
2906
|
/* call-seq:
|
2722
2907
|
* BigDecimal.limit(digits)
|
2723
2908
|
*
|
@@ -2734,7 +2919,7 @@ static VALUE
|
|
2734
2919
|
BigDecimal_limit(int argc, VALUE *argv, VALUE self)
|
2735
2920
|
{
|
2736
2921
|
VALUE nFig;
|
2737
|
-
VALUE nCur =
|
2922
|
+
VALUE nCur = SIZET2NUM(VpGetPrecLimit());
|
2738
2923
|
|
2739
2924
|
if (rb_scan_args(argc, argv, "01", &nFig) == 1) {
|
2740
2925
|
int nf;
|
@@ -2899,7 +3084,7 @@ BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec)
|
|
2899
3084
|
infinite = isinf(flo);
|
2900
3085
|
nan = isnan(flo);
|
2901
3086
|
if (!infinite && !nan) {
|
2902
|
-
vx = GetVpValueWithPrec(x,
|
3087
|
+
vx = GetVpValueWithPrec(x, DBLE_FIG, 0);
|
2903
3088
|
}
|
2904
3089
|
break;
|
2905
3090
|
|
@@ -2937,6 +3122,10 @@ BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec)
|
|
2937
3122
|
n = prec + rmpd_double_figures();
|
2938
3123
|
negative = BIGDECIMAL_NEGATIVE_P(vx);
|
2939
3124
|
if (negative) {
|
3125
|
+
VALUE x_zero = INT2NUM(1);
|
3126
|
+
VALUE x_copy = f_BigDecimal(1, &x_zero, klass);
|
3127
|
+
x = BigDecimal_initialize_copy(x_copy, x);
|
3128
|
+
vx = DATA_PTR(x);
|
2940
3129
|
VpSetSign(vx, 1);
|
2941
3130
|
}
|
2942
3131
|
|
@@ -3048,7 +3237,7 @@ get_vp_value:
|
|
3048
3237
|
infinite = isinf(flo);
|
3049
3238
|
nan = isnan(flo);
|
3050
3239
|
if (!zero && !negative && !infinite && !nan) {
|
3051
|
-
vx = GetVpValueWithPrec(x,
|
3240
|
+
vx = GetVpValueWithPrec(x, DBLE_FIG, 1);
|
3052
3241
|
}
|
3053
3242
|
break;
|
3054
3243
|
|
@@ -3266,6 +3455,9 @@ get_vp_value:
|
|
3266
3455
|
void
|
3267
3456
|
Init_bigdecimal(void)
|
3268
3457
|
{
|
3458
|
+
#ifdef HAVE_RB_EXT_RACTOR_SAFE
|
3459
|
+
rb_ext_ractor_safe(true);
|
3460
|
+
#endif
|
3269
3461
|
VALUE arg;
|
3270
3462
|
|
3271
3463
|
id_BigDecimal_exception_mode = rb_intern_const("BigDecimal.exception_mode");
|
@@ -3277,18 +3469,18 @@ Init_bigdecimal(void)
|
|
3277
3469
|
|
3278
3470
|
/* Class and method registration */
|
3279
3471
|
rb_cBigDecimal = rb_define_class("BigDecimal", rb_cNumeric);
|
3280
|
-
rb_define_alloc_func(rb_cBigDecimal, BigDecimal_s_allocate);
|
3281
3472
|
|
3282
3473
|
/* Global function */
|
3283
|
-
rb_define_global_function("BigDecimal",
|
3474
|
+
rb_define_global_function("BigDecimal", f_BigDecimal, -1);
|
3284
3475
|
|
3285
3476
|
/* Class methods */
|
3286
|
-
|
3477
|
+
rb_undef_alloc_func(rb_cBigDecimal);
|
3478
|
+
rb_undef_method(CLASS_OF(rb_cBigDecimal), "new");
|
3479
|
+
rb_define_singleton_method(rb_cBigDecimal, "interpret_loosely", BigDecimal_s_interpret_loosely, 1);
|
3287
3480
|
rb_define_singleton_method(rb_cBigDecimal, "mode", BigDecimal_mode, -1);
|
3288
3481
|
rb_define_singleton_method(rb_cBigDecimal, "limit", BigDecimal_limit, -1);
|
3289
3482
|
rb_define_singleton_method(rb_cBigDecimal, "double_fig", BigDecimal_double_fig, 0);
|
3290
3483
|
rb_define_singleton_method(rb_cBigDecimal, "_load", BigDecimal_load, 1);
|
3291
|
-
rb_define_singleton_method(rb_cBigDecimal, "ver", BigDecimal_version, 0);
|
3292
3484
|
|
3293
3485
|
rb_define_singleton_method(rb_cBigDecimal, "save_exception_mode", BigDecimal_save_exception_mode, 0);
|
3294
3486
|
rb_define_singleton_method(rb_cBigDecimal, "save_rounding_mode", BigDecimal_save_rounding_mode, 0);
|
@@ -3408,16 +3600,16 @@ Init_bigdecimal(void)
|
|
3408
3600
|
|
3409
3601
|
arg = rb_str_new2("+Infinity");
|
3410
3602
|
/* Positive infinity value. */
|
3411
|
-
rb_define_const(rb_cBigDecimal, "INFINITY",
|
3603
|
+
rb_define_const(rb_cBigDecimal, "INFINITY", f_BigDecimal(1, &arg, rb_cBigDecimal));
|
3412
3604
|
arg = rb_str_new2("NaN");
|
3413
3605
|
/* 'Not a Number' value. */
|
3414
|
-
rb_define_const(rb_cBigDecimal, "NAN",
|
3606
|
+
rb_define_const(rb_cBigDecimal, "NAN", f_BigDecimal(1, &arg, rb_cBigDecimal));
|
3415
3607
|
|
3416
3608
|
|
3417
3609
|
/* instance methods */
|
3418
|
-
rb_define_method(rb_cBigDecimal, "initialize", BigDecimal_initialize, -1);
|
3419
|
-
rb_define_method(rb_cBigDecimal, "initialize_copy", BigDecimal_initialize_copy, 1);
|
3420
3610
|
rb_define_method(rb_cBigDecimal, "precs", BigDecimal_prec, 0);
|
3611
|
+
rb_define_method(rb_cBigDecimal, "precision", BigDecimal_precision, 0);
|
3612
|
+
rb_define_method(rb_cBigDecimal, "n_significant_digits", BigDecimal_n_significant_digits, 0);
|
3421
3613
|
|
3422
3614
|
rb_define_method(rb_cBigDecimal, "add", BigDecimal_add2, 2);
|
3423
3615
|
rb_define_method(rb_cBigDecimal, "sub", BigDecimal_sub2, 2);
|
@@ -3534,6 +3726,9 @@ static void VpFormatSt(char *psz, size_t fFmt);
|
|
3534
3726
|
static int VpRdup(Real *m, size_t ind_m);
|
3535
3727
|
|
3536
3728
|
#ifdef BIGDECIMAL_DEBUG
|
3729
|
+
# ifdef HAVE_RB_EXT_RACTOR_SAFE
|
3730
|
+
# error Need to make rewiting gnAlloc atomic
|
3731
|
+
# endif
|
3537
3732
|
static int gnAlloc = 0; /* Memory allocation counter */
|
3538
3733
|
#endif /* BIGDECIMAL_DEBUG */
|
3539
3734
|
|
@@ -3714,13 +3909,7 @@ VpSetRoundMode(unsigned short n)
|
|
3714
3909
|
* (to let the compiler know they may be changed in outside
|
3715
3910
|
* (... but not actually..)).
|
3716
3911
|
*/
|
3717
|
-
volatile const double gZero_ABCED9B1_CE73__00400511F31D = 0.0;
|
3718
3912
|
volatile const double gOne_ABCED9B4_CE73__00400511F31D = 1.0;
|
3719
|
-
static double
|
3720
|
-
Zero(void)
|
3721
|
-
{
|
3722
|
-
return gZero_ABCED9B1_CE73__00400511F31D;
|
3723
|
-
}
|
3724
3913
|
|
3725
3914
|
static double
|
3726
3915
|
One(void)
|
@@ -3745,25 +3934,19 @@ One(void)
|
|
3745
3934
|
VP_EXPORT double
|
3746
3935
|
VpGetDoubleNaN(void) /* Returns the value of NaN */
|
3747
3936
|
{
|
3748
|
-
|
3749
|
-
if (fNaN == 0.0) fNaN = Zero()/Zero();
|
3750
|
-
return fNaN;
|
3937
|
+
return nan("");
|
3751
3938
|
}
|
3752
3939
|
|
3753
3940
|
VP_EXPORT double
|
3754
3941
|
VpGetDoublePosInf(void) /* Returns the value of +Infinity */
|
3755
3942
|
{
|
3756
|
-
|
3757
|
-
if (fInf == 0.0) fInf = One()/Zero();
|
3758
|
-
return fInf;
|
3943
|
+
return HUGE_VAL;
|
3759
3944
|
}
|
3760
3945
|
|
3761
3946
|
VP_EXPORT double
|
3762
3947
|
VpGetDoubleNegInf(void) /* Returns the value of -Infinity */
|
3763
3948
|
{
|
3764
|
-
|
3765
|
-
if (fInf == 0.0) fInf = -(One()/Zero());
|
3766
|
-
return fInf;
|
3949
|
+
return -HUGE_VAL;
|
3767
3950
|
}
|
3768
3951
|
|
3769
3952
|
VP_EXPORT double
|
@@ -3952,20 +4135,17 @@ VpNumOfChars(Real *vp,const char *pszFmt)
|
|
3952
4135
|
* by one BDIGIT word in the computer used.
|
3953
4136
|
*
|
3954
4137
|
* [Returns]
|
3955
|
-
*
|
4138
|
+
* DBLE_FIG ... OK
|
3956
4139
|
*/
|
3957
4140
|
VP_EXPORT size_t
|
3958
4141
|
VpInit(BDIGIT BaseVal)
|
3959
4142
|
{
|
3960
4143
|
/* Setup +/- Inf NaN -0 */
|
3961
|
-
VpGetDoubleNaN();
|
3962
|
-
VpGetDoublePosInf();
|
3963
|
-
VpGetDoubleNegInf();
|
3964
4144
|
VpGetDoubleNegZero();
|
3965
4145
|
|
3966
4146
|
/* Allocates Vp constants. */
|
3967
|
-
VpConstOne = VpAlloc(1UL, "1");
|
3968
|
-
VpPt5 = VpAlloc(1UL, ".5");
|
4147
|
+
VpConstOne = VpAlloc(1UL, "1", 1, 1);
|
4148
|
+
VpPt5 = VpAlloc(1UL, ".5", 1, 1);
|
3969
4149
|
|
3970
4150
|
#ifdef BIGDECIMAL_DEBUG
|
3971
4151
|
gnAlloc = 0;
|
@@ -4029,6 +4209,52 @@ overflow:
|
|
4029
4209
|
return VpException(VP_EXCEPTION_OVERFLOW, "Exponent overflow", 0);
|
4030
4210
|
}
|
4031
4211
|
|
4212
|
+
Real *
|
4213
|
+
rmpd_parse_special_string(const char *str)
|
4214
|
+
{
|
4215
|
+
static const struct {
|
4216
|
+
const char *str;
|
4217
|
+
size_t len;
|
4218
|
+
int sign;
|
4219
|
+
} table[] = {
|
4220
|
+
{ SZ_INF, sizeof(SZ_INF) - 1, VP_SIGN_POSITIVE_INFINITE },
|
4221
|
+
{ SZ_PINF, sizeof(SZ_PINF) - 1, VP_SIGN_POSITIVE_INFINITE },
|
4222
|
+
{ SZ_NINF, sizeof(SZ_NINF) - 1, VP_SIGN_NEGATIVE_INFINITE },
|
4223
|
+
{ SZ_NaN, sizeof(SZ_NaN) - 1, VP_SIGN_NaN }
|
4224
|
+
};
|
4225
|
+
static const size_t table_length = sizeof(table) / sizeof(table[0]);
|
4226
|
+
size_t i;
|
4227
|
+
|
4228
|
+
for (i = 0; i < table_length; ++i) {
|
4229
|
+
const char *p;
|
4230
|
+
if (strncmp(str, table[i].str, table[i].len) != 0) {
|
4231
|
+
continue;
|
4232
|
+
}
|
4233
|
+
|
4234
|
+
p = str + table[i].len;
|
4235
|
+
while (*p && ISSPACE(*p)) ++p;
|
4236
|
+
if (*p == '\0') {
|
4237
|
+
Real *vp = VpAllocReal(1);
|
4238
|
+
vp->MaxPrec = 1;
|
4239
|
+
switch (table[i].sign) {
|
4240
|
+
default:
|
4241
|
+
UNREACHABLE; break;
|
4242
|
+
case VP_SIGN_POSITIVE_INFINITE:
|
4243
|
+
VpSetPosInf(vp);
|
4244
|
+
return vp;
|
4245
|
+
case VP_SIGN_NEGATIVE_INFINITE:
|
4246
|
+
VpSetNegInf(vp);
|
4247
|
+
return vp;
|
4248
|
+
case VP_SIGN_NaN:
|
4249
|
+
VpSetNaN(vp);
|
4250
|
+
return vp;
|
4251
|
+
}
|
4252
|
+
}
|
4253
|
+
}
|
4254
|
+
|
4255
|
+
return NULL;
|
4256
|
+
}
|
4257
|
+
|
4032
4258
|
/*
|
4033
4259
|
* Allocates variable.
|
4034
4260
|
* [Input]
|
@@ -4043,10 +4269,10 @@ overflow:
|
|
4043
4269
|
* NULL be returned if memory allocation is failed,or any error.
|
4044
4270
|
*/
|
4045
4271
|
VP_EXPORT Real *
|
4046
|
-
VpAlloc(size_t mx, const char *szVal)
|
4272
|
+
VpAlloc(size_t mx, const char *szVal, int strict_p, int exc)
|
4047
4273
|
{
|
4048
4274
|
const char *orig_szVal = szVal;
|
4049
|
-
size_t i,
|
4275
|
+
size_t i, j, ni, ipf, nf, ipe, ne, dot_seen, exp_seen, nalloc;
|
4050
4276
|
char v, *psz;
|
4051
4277
|
int sign=1;
|
4052
4278
|
Real *vp = NULL;
|
@@ -4057,7 +4283,10 @@ VpAlloc(size_t mx, const char *szVal)
|
|
4057
4283
|
if (mx == 0) ++mx;
|
4058
4284
|
|
4059
4285
|
if (szVal) {
|
4286
|
+
/* Skipping leading spaces */
|
4060
4287
|
while (ISSPACE(*szVal)) szVal++;
|
4288
|
+
|
4289
|
+
/* Processing the leading one `#` */
|
4061
4290
|
if (*szVal != '#') {
|
4062
4291
|
if (mf) {
|
4063
4292
|
mf = (mf + BASE_FIG - 1) / BASE_FIG + 2; /* Needs 1 more for div */
|
@@ -4071,115 +4300,179 @@ VpAlloc(size_t mx, const char *szVal)
|
|
4071
4300
|
}
|
4072
4301
|
}
|
4073
4302
|
else {
|
4303
|
+
return_zero:
|
4074
4304
|
/* necessary to be able to store */
|
4075
4305
|
/* at least mx digits. */
|
4076
4306
|
/* szVal==NULL ==> allocate zero value. */
|
4077
4307
|
vp = VpAllocReal(mx);
|
4078
|
-
/* xmalloc()
|
4308
|
+
/* xmalloc() always returns(or throw interruption) */
|
4079
4309
|
vp->MaxPrec = mx; /* set max precision */
|
4080
4310
|
VpSetZero(vp, 1); /* initialize vp to zero. */
|
4081
4311
|
return vp;
|
4082
4312
|
}
|
4083
4313
|
|
4084
|
-
/*
|
4085
|
-
|
4314
|
+
/* Check on Inf & NaN */
|
4315
|
+
if ((vp = rmpd_parse_special_string(szVal)) != NULL) {
|
4316
|
+
return vp;
|
4317
|
+
}
|
4318
|
+
|
4319
|
+
/* Scanning digits */
|
4320
|
+
|
4321
|
+
/* A buffer for keeping scanned digits */
|
4086
4322
|
buf = rb_str_tmp_new(strlen(szVal) + 1);
|
4087
4323
|
psz = RSTRING_PTR(buf);
|
4088
|
-
|
4089
|
-
|
4090
|
-
|
4091
|
-
|
4092
|
-
|
4324
|
+
|
4325
|
+
/* cursor: i for psz, and j for szVal */
|
4326
|
+
i = j = 0;
|
4327
|
+
|
4328
|
+
/* Scanning: sign part */
|
4329
|
+
v = psz[i] = szVal[j];
|
4330
|
+
if ((v == '-') || (v == '+')) {
|
4331
|
+
sign = -(v == '-');
|
4332
|
+
++i;
|
4333
|
+
++j;
|
4334
|
+
}
|
4335
|
+
|
4336
|
+
/* Scanning: integer part */
|
4337
|
+
ni = 0; /* number of digits in the integer part */
|
4338
|
+
while ((v = psz[i] = szVal[j]) != '\0') {
|
4339
|
+
if (!strict_p && ISSPACE(v)) {
|
4340
|
+
v = psz[i] = '\0';
|
4093
4341
|
break;
|
4094
4342
|
}
|
4095
|
-
if (
|
4096
|
-
if (psz[i] == '_') {
|
4343
|
+
if (v == '_') {
|
4097
4344
|
if (ni > 0) {
|
4098
|
-
|
4099
|
-
|
4345
|
+
v = szVal[j+1];
|
4346
|
+
if (v == '\0' || ISSPACE(v) || ISDIGIT(v)) {
|
4347
|
+
++j;
|
4348
|
+
continue;
|
4349
|
+
}
|
4350
|
+
if (!strict_p) {
|
4351
|
+
v = psz[i] = '\0';
|
4352
|
+
break;
|
4353
|
+
}
|
4100
4354
|
}
|
4101
|
-
|
4355
|
+
goto invalid_value;
|
4356
|
+
}
|
4357
|
+
if (!ISDIGIT(v)) {
|
4102
4358
|
break;
|
4103
4359
|
}
|
4360
|
+
++ni;
|
4104
4361
|
++i;
|
4105
|
-
++
|
4362
|
+
++j;
|
4106
4363
|
}
|
4107
|
-
szVal = psz;
|
4108
4364
|
|
4109
|
-
/*
|
4110
|
-
|
4111
|
-
|
4112
|
-
|
4113
|
-
|
4114
|
-
return vp;
|
4115
|
-
}
|
4116
|
-
if (StrCmp(szVal, SZ_NINF) == 0) {
|
4117
|
-
vp = VpAllocReal(1);
|
4118
|
-
vp->MaxPrec = 1; /* set max precision */
|
4119
|
-
VpSetNegInf(vp);
|
4120
|
-
return vp;
|
4121
|
-
}
|
4122
|
-
if (StrCmp(szVal, SZ_NaN) == 0) {
|
4123
|
-
vp = VpAllocReal(1);
|
4124
|
-
vp->MaxPrec = 1; /* set max precision */
|
4125
|
-
VpSetNaN(vp);
|
4126
|
-
return vp;
|
4127
|
-
}
|
4128
|
-
|
4129
|
-
/* check on number szVal[] */
|
4130
|
-
ipn = i = 0;
|
4131
|
-
if (szVal[i] == '-') { sign=-1; ++i; }
|
4132
|
-
else if (szVal[i] == '+') ++i;
|
4133
|
-
/* Skip digits */
|
4134
|
-
ni = 0; /* digits in mantissa */
|
4135
|
-
while ((v = szVal[i]) != 0) {
|
4136
|
-
if (!ISDIGIT(v)) break;
|
4137
|
-
++i;
|
4138
|
-
++ni;
|
4139
|
-
}
|
4140
|
-
nf = 0;
|
4141
|
-
ipf = 0;
|
4142
|
-
ipe = 0;
|
4143
|
-
ne = 0;
|
4365
|
+
/* Scanning: fractional part */
|
4366
|
+
nf = 0; /* number of digits in the fractional part */
|
4367
|
+
ne = 0; /* number of digits in the exponential part */
|
4368
|
+
ipf = 0; /* index of the beginning of the fractional part */
|
4369
|
+
ipe = 0; /* index of the beginning of the exponential part */
|
4144
4370
|
dot_seen = 0;
|
4145
4371
|
exp_seen = 0;
|
4146
|
-
|
4147
|
-
|
4148
|
-
|
4372
|
+
|
4373
|
+
if (v != '\0') {
|
4374
|
+
/* Scanning fractional part */
|
4375
|
+
if ((psz[i] = szVal[j]) == '.') {
|
4149
4376
|
dot_seen = 1;
|
4150
4377
|
++i;
|
4378
|
+
++j;
|
4151
4379
|
ipf = i;
|
4152
|
-
while ((v =
|
4380
|
+
while ((v = psz[i] = szVal[j]) != '\0') {
|
4381
|
+
if (!strict_p && ISSPACE(v)) {
|
4382
|
+
v = psz[i] = '\0';
|
4383
|
+
break;
|
4384
|
+
}
|
4385
|
+
if (v == '_') {
|
4386
|
+
if (nf > 0 && ISDIGIT(szVal[j+1])) {
|
4387
|
+
++j;
|
4388
|
+
continue;
|
4389
|
+
}
|
4390
|
+
if (!strict_p) {
|
4391
|
+
v = psz[i] = '\0';
|
4392
|
+
if (nf == 0) {
|
4393
|
+
dot_seen = 0;
|
4394
|
+
}
|
4395
|
+
break;
|
4396
|
+
}
|
4397
|
+
goto invalid_value;
|
4398
|
+
}
|
4153
4399
|
if (!ISDIGIT(v)) break;
|
4154
4400
|
++i;
|
4401
|
+
++j;
|
4155
4402
|
++nf;
|
4156
4403
|
}
|
4157
4404
|
}
|
4158
|
-
|
4159
|
-
|
4160
|
-
|
4161
|
-
|
4162
|
-
|
4163
|
-
|
4164
|
-
|
4165
|
-
|
4166
|
-
|
4167
|
-
ipe = i;
|
4168
|
-
v = szVal[i];
|
4169
|
-
if ((v == '-') || (v == '+')) ++i;
|
4170
|
-
while ((v=szVal[i]) != 0) {
|
4171
|
-
if (!ISDIGIT(v)) break;
|
4405
|
+
|
4406
|
+
/* Scanning exponential part */
|
4407
|
+
if (v != '\0') {
|
4408
|
+
switch ((psz[i] = szVal[j])) {
|
4409
|
+
case '\0':
|
4410
|
+
break;
|
4411
|
+
case 'e': case 'E':
|
4412
|
+
case 'd': case 'D':
|
4413
|
+
exp_seen = 1;
|
4172
4414
|
++i;
|
4173
|
-
++
|
4174
|
-
|
4175
|
-
|
4176
|
-
|
4177
|
-
|
4415
|
+
++j;
|
4416
|
+
ipe = i;
|
4417
|
+
v = psz[i] = szVal[j];
|
4418
|
+
if ((v == '-') || (v == '+')) {
|
4419
|
+
++i;
|
4420
|
+
++j;
|
4421
|
+
}
|
4422
|
+
while ((v = psz[i] = szVal[j]) != '\0') {
|
4423
|
+
if (!strict_p && ISSPACE(v)) {
|
4424
|
+
v = psz[i] = '\0';
|
4425
|
+
break;
|
4426
|
+
}
|
4427
|
+
if (v == '_') {
|
4428
|
+
if (ne > 0 && ISDIGIT(szVal[j+1])) {
|
4429
|
+
++j;
|
4430
|
+
continue;
|
4431
|
+
}
|
4432
|
+
if (!strict_p) {
|
4433
|
+
v = psz[i] = '\0';
|
4434
|
+
if (ne == 0) {
|
4435
|
+
exp_seen = 0;
|
4436
|
+
}
|
4437
|
+
break;
|
4438
|
+
}
|
4439
|
+
goto invalid_value;
|
4440
|
+
}
|
4441
|
+
if (!ISDIGIT(v)) break;
|
4442
|
+
++i;
|
4443
|
+
++j;
|
4444
|
+
++ne;
|
4445
|
+
}
|
4446
|
+
break;
|
4447
|
+
default:
|
4448
|
+
break;
|
4449
|
+
}
|
4450
|
+
}
|
4451
|
+
|
4452
|
+
if (v != '\0') {
|
4453
|
+
/* Scanning trailing spaces */
|
4454
|
+
while (ISSPACE(szVal[j])) ++j;
|
4455
|
+
|
4456
|
+
/* Invalid character */
|
4457
|
+
if (szVal[j] && strict_p) {
|
4458
|
+
goto invalid_value;
|
4459
|
+
}
|
4178
4460
|
}
|
4179
4461
|
}
|
4180
|
-
|
4181
|
-
|
4182
|
-
|
4462
|
+
|
4463
|
+
psz[i] = '\0';
|
4464
|
+
|
4465
|
+
if (strict_p && (((ni == 0 || dot_seen) && nf == 0) || (exp_seen && ne == 0))) {
|
4466
|
+
VALUE str;
|
4467
|
+
invalid_value:
|
4468
|
+
if (!strict_p) {
|
4469
|
+
goto return_zero;
|
4470
|
+
}
|
4471
|
+
if (!exc) {
|
4472
|
+
return NULL;
|
4473
|
+
}
|
4474
|
+
str = rb_str_new2(orig_szVal);
|
4475
|
+
rb_raise(rb_eArgError, "invalid value for BigDecimal(): \"%"PRIsVALUE"\"", str);
|
4183
4476
|
}
|
4184
4477
|
|
4185
4478
|
nalloc = (ni + nf + BASE_FIG - 1) / BASE_FIG + 1; /* set effective allocation */
|
@@ -4188,10 +4481,10 @@ VpAlloc(size_t mx, const char *szVal)
|
|
4188
4481
|
nalloc = Max(nalloc, mx);
|
4189
4482
|
mx = nalloc;
|
4190
4483
|
vp = VpAllocReal(mx);
|
4191
|
-
/* xmalloc()
|
4484
|
+
/* xmalloc() always returns(or throw interruption) */
|
4192
4485
|
vp->MaxPrec = mx; /* set max precision */
|
4193
4486
|
VpSetZero(vp, sign);
|
4194
|
-
VpCtoV(vp,
|
4487
|
+
VpCtoV(vp, psz, ni, psz + ipf, nf, psz + ipe, ne);
|
4195
4488
|
rb_str_resize(buf, 0);
|
4196
4489
|
return vp;
|
4197
4490
|
}
|
@@ -4754,7 +5047,7 @@ VpMult(Real *c, Real *a, Real *b)
|
|
4754
5047
|
|
4755
5048
|
if (MxIndC < MxIndAB) { /* The Max. prec. of c < Prec(a)+Prec(b) */
|
4756
5049
|
w = c;
|
4757
|
-
c = VpAlloc((size_t)((MxIndAB + 1) * BASE_FIG), "#0");
|
5050
|
+
c = VpAlloc((size_t)((MxIndAB + 1) * BASE_FIG), "#0", 1, 1);
|
4758
5051
|
MxIndC = MxIndAB;
|
4759
5052
|
}
|
4760
5053
|
|
@@ -5922,8 +6215,8 @@ VpSqrt(Real *y, Real *x)
|
|
5922
6215
|
if (x->MaxPrec > (size_t)n) n = (ssize_t)x->MaxPrec;
|
5923
6216
|
|
5924
6217
|
/* allocate temporally variables */
|
5925
|
-
f = VpAlloc(y->MaxPrec * (BASE_FIG + 2), "#1");
|
5926
|
-
r = VpAlloc((n + n) * (BASE_FIG + 2), "#1");
|
6218
|
+
f = VpAlloc(y->MaxPrec * (BASE_FIG + 2), "#1", 1, 1);
|
6219
|
+
r = VpAlloc((n + n) * (BASE_FIG + 2), "#1", 1, 1);
|
5927
6220
|
|
5928
6221
|
nr = 0;
|
5929
6222
|
y_prec = y->MaxPrec;
|
@@ -6375,8 +6668,8 @@ VpPower(Real *y, Real *x, SIGNED_VALUE n)
|
|
6375
6668
|
|
6376
6669
|
/* Allocate working variables */
|
6377
6670
|
|
6378
|
-
w1 = VpAlloc((y->MaxPrec + 2) * BASE_FIG, "#0");
|
6379
|
-
w2 = VpAlloc((w1->MaxPrec * 2 + 1) * BASE_FIG, "#0");
|
6671
|
+
w1 = VpAlloc((y->MaxPrec + 2) * BASE_FIG, "#0", 1, 1);
|
6672
|
+
w2 = VpAlloc((w1->MaxPrec * 2 + 1) * BASE_FIG, "#0", 1, 1);
|
6380
6673
|
/* calculation start */
|
6381
6674
|
|
6382
6675
|
VpAsgn(y, x, 1);
|