bigdecimal 1.3.5 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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);
|