bigdecimal 4.0.1 → 4.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bigdecimal.gemspec +6 -1
- data/ext/bigdecimal/bigdecimal.c +262 -261
- data/ext/bigdecimal/bigdecimal.h +43 -37
- data/ext/bigdecimal/div.h +192 -0
- data/ext/bigdecimal/extconf.rb +5 -2
- data/ext/bigdecimal/missing/dtoa.c +184 -137
- data/ext/bigdecimal/missing.h +4 -2
- data/ext/bigdecimal/ntt.h +191 -0
- data/lib/bigdecimal/math.rb +102 -123
- data/lib/bigdecimal/util.rb +1 -1
- data/lib/bigdecimal.rb +104 -60
- data/sample/linear.rb +73 -37
- data/sample/nlsolve.rb +47 -30
- data/sample/pi.rb +2 -7
- data/sig/big_decimal.rbs +1502 -0
- data/sig/big_decimal_util.rbs +158 -0
- data/sig/big_math.rbs +423 -0
- metadata +7 -2
|
@@ -98,17 +98,6 @@
|
|
|
98
98
|
* if memory is available and otherwise does something you deem
|
|
99
99
|
* appropriate. If MALLOC is undefined, malloc will be invoked
|
|
100
100
|
* directly -- and assumed always to succeed.
|
|
101
|
-
* #define Omit_Private_Memory to omit logic (added Jan. 1998) for making
|
|
102
|
-
* memory allocations from a private pool of memory when possible.
|
|
103
|
-
* When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes,
|
|
104
|
-
* unless #defined to be a different length. This default length
|
|
105
|
-
* suffices to get rid of MALLOC calls except for unusual cases,
|
|
106
|
-
* such as decimal-to-binary conversion of a very long string of
|
|
107
|
-
* digits. The longest string dtoa can return is about 751 bytes
|
|
108
|
-
* long. For conversions by strtod of strings of 800 digits and
|
|
109
|
-
* all dtoa conversions in single-threaded executions with 8-byte
|
|
110
|
-
* pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte
|
|
111
|
-
* pointers, PRIVATE_MEM >= 7112 appears adequate.
|
|
112
101
|
* #define INFNAN_CHECK on IEEE systems to cause strtod to check for
|
|
113
102
|
* Infinity and NaN (case insensitively). On some systems (e.g.,
|
|
114
103
|
* some HP systems), it may be necessary to #define NAN_WORD0
|
|
@@ -183,7 +172,10 @@
|
|
|
183
172
|
#undef Long
|
|
184
173
|
#undef ULong
|
|
185
174
|
|
|
175
|
+
#include <assert.h>
|
|
186
176
|
#include <limits.h>
|
|
177
|
+
#include <stddef.h>
|
|
178
|
+
#include <stdint.h>
|
|
187
179
|
|
|
188
180
|
#if (INT_MAX >> 30) && !(INT_MAX >> 31)
|
|
189
181
|
#define Long int
|
|
@@ -195,7 +187,7 @@
|
|
|
195
187
|
#error No 32bit integer
|
|
196
188
|
#endif
|
|
197
189
|
|
|
198
|
-
#if HAVE_LONG_LONG
|
|
190
|
+
#if defined(HAVE_LONG_LONG) && (HAVE_LONG_LONG)
|
|
199
191
|
#define Llong LONG_LONG
|
|
200
192
|
#else
|
|
201
193
|
#define NO_LONG_LONG
|
|
@@ -218,28 +210,43 @@
|
|
|
218
210
|
#include <locale.h>
|
|
219
211
|
#endif
|
|
220
212
|
|
|
213
|
+
#if defined(HAVE_STDCKDINT_H) || !defined(__has_include)
|
|
214
|
+
#elif __has_include(<stdckdint.h>)
|
|
215
|
+
# define HAVE_STDCKDINT_H 1
|
|
216
|
+
#endif
|
|
217
|
+
#ifdef HAVE_STDCKDINT_H
|
|
218
|
+
# include <stdckdint.h>
|
|
219
|
+
#endif
|
|
220
|
+
|
|
221
|
+
#if !defined(ckd_add)
|
|
222
|
+
static inline int /* bool */
|
|
223
|
+
ckd_add(int *result, int x, int y)
|
|
224
|
+
{
|
|
225
|
+
if (x < 0) {
|
|
226
|
+
if (y < INT_MIN - x) return 1;
|
|
227
|
+
}
|
|
228
|
+
else if (x > 0) {
|
|
229
|
+
if (y > INT_MAX - x) return 1;
|
|
230
|
+
}
|
|
231
|
+
*result = x + y;
|
|
232
|
+
return 0;
|
|
233
|
+
}
|
|
234
|
+
#endif
|
|
235
|
+
|
|
221
236
|
#ifdef MALLOC
|
|
222
237
|
extern void *MALLOC(size_t);
|
|
223
238
|
#else
|
|
224
|
-
#define MALLOC
|
|
239
|
+
#define MALLOC malloc
|
|
225
240
|
#endif
|
|
226
241
|
#ifdef FREE
|
|
227
242
|
extern void FREE(void*);
|
|
228
243
|
#else
|
|
229
|
-
#define FREE
|
|
244
|
+
#define FREE free
|
|
230
245
|
#endif
|
|
231
246
|
#ifndef NO_SANITIZE
|
|
232
247
|
#define NO_SANITIZE(x, y) y
|
|
233
248
|
#endif
|
|
234
249
|
|
|
235
|
-
#ifndef Omit_Private_Memory
|
|
236
|
-
#ifndef PRIVATE_MEM
|
|
237
|
-
#define PRIVATE_MEM 2304
|
|
238
|
-
#endif
|
|
239
|
-
#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
|
|
240
|
-
static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
|
|
241
|
-
#endif
|
|
242
|
-
|
|
243
250
|
#undef IEEE_Arith
|
|
244
251
|
#undef Avoid_Underflow
|
|
245
252
|
#ifdef IEEE_BIG_ENDIAN
|
|
@@ -502,7 +509,7 @@ extern double rnd_prod(double, double), rnd_quot(double, double);
|
|
|
502
509
|
#endif
|
|
503
510
|
|
|
504
511
|
#ifndef ATOMIC_PTR_CAS
|
|
505
|
-
#define ATOMIC_PTR_CAS(var, old, new) ((var) = (new), (old))
|
|
512
|
+
#define ATOMIC_PTR_CAS(var, old, new) ((var) = (new), (void *)(old))
|
|
506
513
|
#endif
|
|
507
514
|
#ifndef LIKELY
|
|
508
515
|
#define LIKELY(x) (x)
|
|
@@ -524,76 +531,29 @@ struct Bigint {
|
|
|
524
531
|
|
|
525
532
|
typedef struct Bigint Bigint;
|
|
526
533
|
|
|
527
|
-
static Bigint *freelist[Kmax+1];
|
|
528
|
-
|
|
529
534
|
static Bigint *
|
|
530
535
|
Balloc(int k)
|
|
531
536
|
{
|
|
532
537
|
int x;
|
|
533
538
|
Bigint *rv;
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
rv =
|
|
539
|
-
|
|
540
|
-
if (k <= Kmax) {
|
|
541
|
-
rv = freelist[k];
|
|
542
|
-
while (rv) {
|
|
543
|
-
Bigint *rvn = rv;
|
|
544
|
-
rv = ATOMIC_PTR_CAS(freelist[k], rv, rv->next);
|
|
545
|
-
if (LIKELY(rvn == rv)) {
|
|
546
|
-
ASSUME(rv);
|
|
547
|
-
break;
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
if (!rv) {
|
|
552
|
-
x = 1 << k;
|
|
553
|
-
#ifdef Omit_Private_Memory
|
|
554
|
-
rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
|
|
555
|
-
#else
|
|
556
|
-
len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
|
|
557
|
-
/sizeof(double);
|
|
558
|
-
if (k <= Kmax) {
|
|
559
|
-
double *pnext = pmem_next;
|
|
560
|
-
while (pnext - private_mem + len <= PRIVATE_mem) {
|
|
561
|
-
double *p = pnext;
|
|
562
|
-
pnext = ATOMIC_PTR_CAS(pmem_next, pnext, pnext + len);
|
|
563
|
-
if (LIKELY(p == pnext)) {
|
|
564
|
-
rv = (Bigint*)pnext;
|
|
565
|
-
ASSUME(rv);
|
|
566
|
-
break;
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
if (!rv)
|
|
571
|
-
rv = (Bigint*)MALLOC(len*sizeof(double));
|
|
572
|
-
#endif
|
|
573
|
-
rv->k = k;
|
|
574
|
-
rv->maxwds = x;
|
|
575
|
-
}
|
|
576
|
-
FREE_DTOA_LOCK(0);
|
|
539
|
+
|
|
540
|
+
x = 1 << k;
|
|
541
|
+
rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
|
|
542
|
+
if (!rv) return NULL;
|
|
543
|
+
rv->k = k;
|
|
544
|
+
rv->maxwds = x;
|
|
577
545
|
rv->sign = rv->wds = 0;
|
|
578
546
|
return rv;
|
|
579
547
|
}
|
|
580
548
|
|
|
581
549
|
static void
|
|
582
|
-
|
|
550
|
+
Bclear(Bigint **vp)
|
|
583
551
|
{
|
|
584
|
-
Bigint *
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
FREE(v);
|
|
588
|
-
return;
|
|
589
|
-
}
|
|
590
|
-
ACQUIRE_DTOA_LOCK(0);
|
|
591
|
-
do {
|
|
592
|
-
vn = v->next = freelist[v->k];
|
|
593
|
-
} while (UNLIKELY(ATOMIC_PTR_CAS(freelist[v->k], vn, v) != vn));
|
|
594
|
-
FREE_DTOA_LOCK(0);
|
|
595
|
-
}
|
|
552
|
+
Bigint *v = *vp;
|
|
553
|
+
*vp = NULL;
|
|
554
|
+
if (v) FREE(v);
|
|
596
555
|
}
|
|
556
|
+
#define Bfree(v) Bclear(&(v))
|
|
597
557
|
|
|
598
558
|
#define Bcopy(x,y) memcpy((char *)&(x)->sign, (char *)&(y)->sign, \
|
|
599
559
|
(y)->wds*sizeof(Long) + 2*sizeof(int))
|
|
@@ -639,6 +599,10 @@ multadd(Bigint *b, int m, int a) /* multiply by m and add a */
|
|
|
639
599
|
if (carry) {
|
|
640
600
|
if (wds >= b->maxwds) {
|
|
641
601
|
b1 = Balloc(b->k+1);
|
|
602
|
+
if (!b1) {
|
|
603
|
+
Bfree(b);
|
|
604
|
+
return NULL;
|
|
605
|
+
}
|
|
642
606
|
Bcopy(b1, b);
|
|
643
607
|
Bfree(b);
|
|
644
608
|
b = b1;
|
|
@@ -660,10 +624,12 @@ s2b(const char *s, int nd0, int nd, ULong y9)
|
|
|
660
624
|
for (k = 0, y = 1; x > y; y <<= 1, k++) ;
|
|
661
625
|
#ifdef Pack_32
|
|
662
626
|
b = Balloc(k);
|
|
627
|
+
if (!b) return NULL;
|
|
663
628
|
b->x[0] = y9;
|
|
664
629
|
b->wds = 1;
|
|
665
630
|
#else
|
|
666
631
|
b = Balloc(k+1);
|
|
632
|
+
if (!b) return NULL;
|
|
667
633
|
b->x[0] = y9 & 0xffff;
|
|
668
634
|
b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
|
|
669
635
|
#endif
|
|
@@ -673,13 +639,16 @@ s2b(const char *s, int nd0, int nd, ULong y9)
|
|
|
673
639
|
s += 9;
|
|
674
640
|
do {
|
|
675
641
|
b = multadd(b, 10, *s++ - '0');
|
|
642
|
+
if (!b) return NULL;
|
|
676
643
|
} while (++i < nd0);
|
|
677
644
|
s++;
|
|
678
645
|
}
|
|
679
646
|
else
|
|
680
647
|
s += 10;
|
|
681
|
-
for (; i < nd; i++)
|
|
648
|
+
for (; i < nd; i++) {
|
|
682
649
|
b = multadd(b, 10, *s++ - '0');
|
|
650
|
+
if (!b) return NULL;
|
|
651
|
+
}
|
|
683
652
|
return b;
|
|
684
653
|
}
|
|
685
654
|
|
|
@@ -761,11 +730,14 @@ i2b(int i)
|
|
|
761
730
|
Bigint *b;
|
|
762
731
|
|
|
763
732
|
b = Balloc(1);
|
|
733
|
+
if (!b) return NULL;
|
|
764
734
|
b->x[0] = i;
|
|
765
735
|
b->wds = 1;
|
|
766
736
|
return b;
|
|
767
737
|
}
|
|
768
738
|
|
|
739
|
+
#define Bzero_p(b) (!(b)->x[0] && (b)->wds <= 1)
|
|
740
|
+
|
|
769
741
|
static Bigint *
|
|
770
742
|
mult(Bigint *a, Bigint *b)
|
|
771
743
|
{
|
|
@@ -782,6 +754,14 @@ mult(Bigint *a, Bigint *b)
|
|
|
782
754
|
#endif
|
|
783
755
|
#endif
|
|
784
756
|
|
|
757
|
+
if (Bzero_p(a) || Bzero_p(b)) {
|
|
758
|
+
c = Balloc(0);
|
|
759
|
+
if (!c) return NULL;
|
|
760
|
+
c->wds = 1;
|
|
761
|
+
c->x[0] = 0;
|
|
762
|
+
return c;
|
|
763
|
+
}
|
|
764
|
+
|
|
785
765
|
if (a->wds < b->wds) {
|
|
786
766
|
c = a;
|
|
787
767
|
a = b;
|
|
@@ -794,6 +774,7 @@ mult(Bigint *a, Bigint *b)
|
|
|
794
774
|
if (wc > a->maxwds)
|
|
795
775
|
k++;
|
|
796
776
|
c = Balloc(k);
|
|
777
|
+
if (!c) return NULL;
|
|
797
778
|
for (x = c->x, xa = x + wc; x < xa; x++)
|
|
798
779
|
*x = 0;
|
|
799
780
|
xa = a->x;
|
|
@@ -873,50 +854,47 @@ static Bigint *
|
|
|
873
854
|
pow5mult(Bigint *b, int k)
|
|
874
855
|
{
|
|
875
856
|
Bigint *b1, *p5, *p51;
|
|
876
|
-
Bigint *p5tmp;
|
|
877
857
|
int i;
|
|
878
858
|
static const int p05[3] = { 5, 25, 125 };
|
|
879
859
|
|
|
880
|
-
if ((i = k & 3) != 0)
|
|
860
|
+
if ((i = k & 3) != 0) {
|
|
881
861
|
b = multadd(b, p05[i-1], 0);
|
|
862
|
+
if (!b) return NULL;
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
#define b_cache(var, addr, new_expr) \
|
|
866
|
+
if ((var = addr) != 0) {} else { \
|
|
867
|
+
Bigint *tmp = 0; \
|
|
868
|
+
ACQUIRE_DTOA_LOCK(1); \
|
|
869
|
+
if (!(var = addr) && (var = (new_expr)) != 0) { \
|
|
870
|
+
var->next = 0; \
|
|
871
|
+
tmp = ATOMIC_PTR_CAS(addr, NULL, var); \
|
|
872
|
+
} \
|
|
873
|
+
FREE_DTOA_LOCK(1); \
|
|
874
|
+
if (UNLIKELY(tmp)) { \
|
|
875
|
+
Bfree(var); \
|
|
876
|
+
var = tmp; \
|
|
877
|
+
} \
|
|
878
|
+
else if (!var) { \
|
|
879
|
+
Bfree(b); \
|
|
880
|
+
return NULL; \
|
|
881
|
+
} \
|
|
882
|
+
}
|
|
882
883
|
|
|
883
884
|
if (!(k >>= 2))
|
|
884
885
|
return b;
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
ACQUIRE_DTOA_LOCK(1);
|
|
888
|
-
if (!(p5 = p5s)) {
|
|
889
|
-
p5 = i2b(625);
|
|
890
|
-
p5->next = 0;
|
|
891
|
-
p5tmp = ATOMIC_PTR_CAS(p5s, NULL, p5);
|
|
892
|
-
if (UNLIKELY(p5tmp)) {
|
|
893
|
-
Bfree(p5);
|
|
894
|
-
p5 = p5tmp;
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
FREE_DTOA_LOCK(1);
|
|
898
|
-
}
|
|
886
|
+
/* first time */
|
|
887
|
+
b_cache(p5, p5s, i2b(625));
|
|
899
888
|
for (;;) {
|
|
900
889
|
if (k & 1) {
|
|
901
890
|
b1 = mult(b, p5);
|
|
902
891
|
Bfree(b);
|
|
903
892
|
b = b1;
|
|
893
|
+
if (!b) return NULL;
|
|
904
894
|
}
|
|
905
895
|
if (!(k >>= 1))
|
|
906
896
|
break;
|
|
907
|
-
|
|
908
|
-
ACQUIRE_DTOA_LOCK(1);
|
|
909
|
-
if (!(p51 = p5->next)) {
|
|
910
|
-
p51 = mult(p5,p5);
|
|
911
|
-
p51->next = 0;
|
|
912
|
-
p5tmp = ATOMIC_PTR_CAS(p5->next, NULL, p51);
|
|
913
|
-
if (UNLIKELY(p5tmp)) {
|
|
914
|
-
Bfree(p51);
|
|
915
|
-
p51 = p5tmp;
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
FREE_DTOA_LOCK(1);
|
|
919
|
-
}
|
|
897
|
+
b_cache(p51, p5->next, mult(p5, p5));
|
|
920
898
|
p5 = p51;
|
|
921
899
|
}
|
|
922
900
|
return b;
|
|
@@ -929,6 +907,8 @@ lshift(Bigint *b, int k)
|
|
|
929
907
|
Bigint *b1;
|
|
930
908
|
ULong *x, *x1, *xe, z;
|
|
931
909
|
|
|
910
|
+
if (!k || Bzero_p(b)) return b;
|
|
911
|
+
|
|
932
912
|
#ifdef Pack_32
|
|
933
913
|
n = k >> 5;
|
|
934
914
|
#else
|
|
@@ -939,6 +919,10 @@ lshift(Bigint *b, int k)
|
|
|
939
919
|
for (i = b->maxwds; n1 > i; i <<= 1)
|
|
940
920
|
k1++;
|
|
941
921
|
b1 = Balloc(k1);
|
|
922
|
+
if (!b1) {
|
|
923
|
+
Bfree(b);
|
|
924
|
+
return NULL;
|
|
925
|
+
}
|
|
942
926
|
x1 = b1->x;
|
|
943
927
|
for (i = 0; i < n; i++)
|
|
944
928
|
*x1++ = 0;
|
|
@@ -1024,6 +1008,7 @@ diff(Bigint *a, Bigint *b)
|
|
|
1024
1008
|
i = cmp(a,b);
|
|
1025
1009
|
if (!i) {
|
|
1026
1010
|
c = Balloc(0);
|
|
1011
|
+
if (!c) return NULL;
|
|
1027
1012
|
c->wds = 1;
|
|
1028
1013
|
c->x[0] = 0;
|
|
1029
1014
|
return c;
|
|
@@ -1037,6 +1022,7 @@ diff(Bigint *a, Bigint *b)
|
|
|
1037
1022
|
else
|
|
1038
1023
|
i = 0;
|
|
1039
1024
|
c = Balloc(a->k);
|
|
1025
|
+
if (!c) return NULL;
|
|
1040
1026
|
c->sign = i;
|
|
1041
1027
|
wa = a->wds;
|
|
1042
1028
|
xa = a->x;
|
|
@@ -1222,6 +1208,7 @@ d2b(double d_, int *e, int *bits)
|
|
|
1222
1208
|
#else
|
|
1223
1209
|
b = Balloc(2);
|
|
1224
1210
|
#endif
|
|
1211
|
+
if (!b) return NULL;
|
|
1225
1212
|
x = b->x;
|
|
1226
1213
|
|
|
1227
1214
|
z = d0 & Frac_mask;
|
|
@@ -1542,9 +1529,10 @@ break2:
|
|
|
1542
1529
|
aadj = 1.0;
|
|
1543
1530
|
nd0 = -4;
|
|
1544
1531
|
|
|
1545
|
-
if (!*++s || !(s1 = strchr(hexdigit, *s))) goto ret0;
|
|
1532
|
+
if (!*++s || (!(s1 = strchr(hexdigit, *s)) && *s != '.')) goto ret0;
|
|
1546
1533
|
if (*s == '0') {
|
|
1547
1534
|
while (*++s == '0');
|
|
1535
|
+
if (!*s) goto ret;
|
|
1548
1536
|
s1 = strchr(hexdigit, *s);
|
|
1549
1537
|
}
|
|
1550
1538
|
if (s1 != NULL) {
|
|
@@ -1555,9 +1543,7 @@ break2:
|
|
|
1555
1543
|
} while (*++s && (s1 = strchr(hexdigit, *s)));
|
|
1556
1544
|
}
|
|
1557
1545
|
|
|
1558
|
-
if (*s == '.') {
|
|
1559
|
-
dsign = 1;
|
|
1560
|
-
if (!*++s || !(s1 = strchr(hexdigit, *s))) goto ret0;
|
|
1546
|
+
if ((*s == '.') && *++s && (s1 = strchr(hexdigit, *s))) {
|
|
1561
1547
|
if (nd0 < 0) {
|
|
1562
1548
|
while (*s == '0') {
|
|
1563
1549
|
s++;
|
|
@@ -1567,14 +1553,11 @@ break2:
|
|
|
1567
1553
|
for (; *s && (s1 = strchr(hexdigit, *s)); ++s) {
|
|
1568
1554
|
adj += aadj * ((s1 - hexdigit) & 15);
|
|
1569
1555
|
if ((aadj /= 16) == 0.0) {
|
|
1570
|
-
while (strchr(hexdigit,
|
|
1556
|
+
while (*++s && strchr(hexdigit, *s));
|
|
1571
1557
|
break;
|
|
1572
1558
|
}
|
|
1573
1559
|
}
|
|
1574
1560
|
}
|
|
1575
|
-
else {
|
|
1576
|
-
dsign = 0;
|
|
1577
|
-
}
|
|
1578
1561
|
|
|
1579
1562
|
if (*s == 'P' || *s == 'p') {
|
|
1580
1563
|
dsign = 0x2C - *++s; /* +: 2B, -: 2D */
|
|
@@ -1597,9 +1580,6 @@ break2:
|
|
|
1597
1580
|
} while ('0' <= c && c <= '9');
|
|
1598
1581
|
nd0 += nd * dsign;
|
|
1599
1582
|
}
|
|
1600
|
-
else {
|
|
1601
|
-
if (dsign) goto ret0;
|
|
1602
|
-
}
|
|
1603
1583
|
dval(rv) = ldexp(adj, nd0);
|
|
1604
1584
|
goto ret;
|
|
1605
1585
|
}
|
|
@@ -1636,9 +1616,9 @@ break2:
|
|
|
1636
1616
|
}
|
|
1637
1617
|
#endif
|
|
1638
1618
|
if (c == '.') {
|
|
1639
|
-
if (!ISDIGIT(s[1]))
|
|
1640
|
-
goto dig_done;
|
|
1641
1619
|
c = *++s;
|
|
1620
|
+
if (!ISDIGIT(c))
|
|
1621
|
+
goto dig_done;
|
|
1642
1622
|
if (!nd) {
|
|
1643
1623
|
for (; c == '0'; c = *++s)
|
|
1644
1624
|
nz++;
|
|
@@ -1979,12 +1959,16 @@ undfl:
|
|
|
1979
1959
|
/* Put digits into bd: true value = bd * 10^e */
|
|
1980
1960
|
|
|
1981
1961
|
bd0 = s2b(s0, nd0, nd, y);
|
|
1962
|
+
if (!bd0) goto ret;
|
|
1982
1963
|
|
|
1983
1964
|
for (;;) {
|
|
1984
1965
|
bd = Balloc(bd0->k);
|
|
1966
|
+
if (!bd) goto retfree;
|
|
1985
1967
|
Bcopy(bd, bd0);
|
|
1986
1968
|
bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */
|
|
1969
|
+
if (!bb) goto retfree;
|
|
1987
1970
|
bs = i2b(1);
|
|
1971
|
+
if (!bs) goto retfree;
|
|
1988
1972
|
|
|
1989
1973
|
if (e >= 0) {
|
|
1990
1974
|
bb2 = bb5 = 0;
|
|
@@ -2041,19 +2025,30 @@ undfl:
|
|
|
2041
2025
|
}
|
|
2042
2026
|
if (bb5 > 0) {
|
|
2043
2027
|
bs = pow5mult(bs, bb5);
|
|
2028
|
+
if (!bs) goto retfree;
|
|
2044
2029
|
bb1 = mult(bs, bb);
|
|
2045
2030
|
Bfree(bb);
|
|
2046
2031
|
bb = bb1;
|
|
2032
|
+
if (!bb) goto retfree;
|
|
2047
2033
|
}
|
|
2048
|
-
if (bb2 > 0)
|
|
2034
|
+
if (bb2 > 0) {
|
|
2049
2035
|
bb = lshift(bb, bb2);
|
|
2050
|
-
|
|
2036
|
+
if (!bb) goto retfree;
|
|
2037
|
+
}
|
|
2038
|
+
if (bd5 > 0) {
|
|
2051
2039
|
bd = pow5mult(bd, bd5);
|
|
2052
|
-
|
|
2040
|
+
if (!bd) goto retfree;
|
|
2041
|
+
}
|
|
2042
|
+
if (bd2 > 0) {
|
|
2053
2043
|
bd = lshift(bd, bd2);
|
|
2054
|
-
|
|
2044
|
+
if (!bd) goto retfree;
|
|
2045
|
+
}
|
|
2046
|
+
if (bs2 > 0) {
|
|
2055
2047
|
bs = lshift(bs, bs2);
|
|
2048
|
+
if (!bs) goto retfree;
|
|
2049
|
+
}
|
|
2056
2050
|
delta = diff(bb, bd);
|
|
2051
|
+
if (!delta) goto retfree;
|
|
2057
2052
|
dsign = delta->sign;
|
|
2058
2053
|
delta->sign = 0;
|
|
2059
2054
|
i = cmp(delta, bs);
|
|
@@ -2086,6 +2081,7 @@ undfl:
|
|
|
2086
2081
|
#endif
|
|
2087
2082
|
{
|
|
2088
2083
|
delta = lshift(delta,Log2P);
|
|
2084
|
+
if (!delta) goto nomem;
|
|
2089
2085
|
if (cmp(delta, bs) <= 0)
|
|
2090
2086
|
adj = -0.5;
|
|
2091
2087
|
}
|
|
@@ -2175,6 +2171,7 @@ apply_adj:
|
|
|
2175
2171
|
break;
|
|
2176
2172
|
}
|
|
2177
2173
|
delta = lshift(delta,Log2P);
|
|
2174
|
+
if (!delta) goto retfree;
|
|
2178
2175
|
if (cmp(delta, bs) > 0)
|
|
2179
2176
|
goto drop_down;
|
|
2180
2177
|
break;
|
|
@@ -2577,6 +2574,7 @@ nrv_alloc(const char *s, char **rve, size_t n)
|
|
|
2577
2574
|
char *rv, *t;
|
|
2578
2575
|
|
|
2579
2576
|
t = rv = rv_alloc(n);
|
|
2577
|
+
if (!rv) return NULL;
|
|
2580
2578
|
while ((*t = *s++) != 0) t++;
|
|
2581
2579
|
if (rve)
|
|
2582
2580
|
*rve = t;
|
|
@@ -2749,6 +2747,7 @@ dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve)
|
|
|
2749
2747
|
#endif
|
|
2750
2748
|
|
|
2751
2749
|
b = d2b(dval(d), &be, &bbits);
|
|
2750
|
+
if (!b) return NULL;
|
|
2752
2751
|
#ifdef Sudden_Underflow
|
|
2753
2752
|
i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
|
|
2754
2753
|
#else
|
|
@@ -2868,13 +2867,20 @@ dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve)
|
|
|
2868
2867
|
leftright = 0;
|
|
2869
2868
|
/* no break */
|
|
2870
2869
|
case 5:
|
|
2871
|
-
i
|
|
2870
|
+
if (ckd_add(&i, ndigits, k + 1)) { /* k + 1 should be safe */
|
|
2871
|
+
Bfree(b);
|
|
2872
|
+
return NULL;
|
|
2873
|
+
}
|
|
2872
2874
|
ilim = i;
|
|
2873
2875
|
ilim1 = i - 1;
|
|
2874
2876
|
if (i <= 0)
|
|
2875
2877
|
i = 1;
|
|
2876
2878
|
}
|
|
2877
2879
|
s = s0 = rv_alloc(i+1);
|
|
2880
|
+
if (!s) {
|
|
2881
|
+
Bfree(b);
|
|
2882
|
+
return NULL;
|
|
2883
|
+
}
|
|
2878
2884
|
|
|
2879
2885
|
#ifdef Honor_FLT_ROUNDS
|
|
2880
2886
|
if (mode > 1 && rounding != 1)
|
|
@@ -3055,6 +3061,7 @@ bump_up:
|
|
|
3055
3061
|
b2 += i;
|
|
3056
3062
|
s2 += i;
|
|
3057
3063
|
mhi = i2b(1);
|
|
3064
|
+
if (!mhi) goto nomem;
|
|
3058
3065
|
}
|
|
3059
3066
|
if (m2 > 0 && s2 > 0) {
|
|
3060
3067
|
i = m2 < s2 ? m2 : s2;
|
|
@@ -3066,19 +3073,28 @@ bump_up:
|
|
|
3066
3073
|
if (leftright) {
|
|
3067
3074
|
if (m5 > 0) {
|
|
3068
3075
|
mhi = pow5mult(mhi, m5);
|
|
3076
|
+
if (!mhi) goto nomem;
|
|
3069
3077
|
b1 = mult(mhi, b);
|
|
3070
3078
|
Bfree(b);
|
|
3071
3079
|
b = b1;
|
|
3080
|
+
if (!b) goto nomem;
|
|
3072
3081
|
}
|
|
3073
|
-
if ((j = b5 - m5) != 0)
|
|
3082
|
+
if ((j = b5 - m5) != 0) {
|
|
3074
3083
|
b = pow5mult(b, j);
|
|
3084
|
+
if (!b) goto nomem;
|
|
3085
|
+
}
|
|
3075
3086
|
}
|
|
3076
|
-
else
|
|
3087
|
+
else {
|
|
3077
3088
|
b = pow5mult(b, b5);
|
|
3089
|
+
if (!b) goto nomem;
|
|
3090
|
+
}
|
|
3078
3091
|
}
|
|
3079
3092
|
S = i2b(1);
|
|
3080
|
-
if (
|
|
3093
|
+
if (!S) goto nomem;
|
|
3094
|
+
if (s5 > 0) {
|
|
3081
3095
|
S = pow5mult(S, s5);
|
|
3096
|
+
if (!S) goto nomem;
|
|
3097
|
+
}
|
|
3082
3098
|
|
|
3083
3099
|
/* Check for special case that d is a normalized power of 2. */
|
|
3084
3100
|
|
|
@@ -3126,16 +3142,23 @@ bump_up:
|
|
|
3126
3142
|
m2 += i;
|
|
3127
3143
|
s2 += i;
|
|
3128
3144
|
}
|
|
3129
|
-
if (b2 > 0)
|
|
3145
|
+
if (b2 > 0) {
|
|
3130
3146
|
b = lshift(b, b2);
|
|
3131
|
-
|
|
3147
|
+
if (!b) goto nomem;
|
|
3148
|
+
}
|
|
3149
|
+
if (s2 > 0) {
|
|
3132
3150
|
S = lshift(S, s2);
|
|
3151
|
+
if (!S) goto nomem;
|
|
3152
|
+
}
|
|
3133
3153
|
if (k_check) {
|
|
3134
3154
|
if (cmp(b,S) < 0) {
|
|
3135
3155
|
k--;
|
|
3136
3156
|
b = multadd(b, 10, 0); /* we botched the k estimate */
|
|
3137
|
-
if (
|
|
3157
|
+
if (!b) goto nomem;
|
|
3158
|
+
if (leftright) {
|
|
3138
3159
|
mhi = multadd(mhi, 10, 0);
|
|
3160
|
+
if (!mhi) goto nomem;
|
|
3161
|
+
}
|
|
3139
3162
|
ilim = ilim1;
|
|
3140
3163
|
}
|
|
3141
3164
|
}
|
|
@@ -3152,8 +3175,10 @@ one_digit:
|
|
|
3152
3175
|
goto ret;
|
|
3153
3176
|
}
|
|
3154
3177
|
if (leftright) {
|
|
3155
|
-
if (m2 > 0)
|
|
3178
|
+
if (m2 > 0) {
|
|
3156
3179
|
mhi = lshift(mhi, m2);
|
|
3180
|
+
if (!mhi) goto nomem;
|
|
3181
|
+
}
|
|
3157
3182
|
|
|
3158
3183
|
/* Compute mlo -- check for special case
|
|
3159
3184
|
* that d is a normalized power of 2.
|
|
@@ -3162,8 +3187,10 @@ one_digit:
|
|
|
3162
3187
|
mlo = mhi;
|
|
3163
3188
|
if (spec_case) {
|
|
3164
3189
|
mhi = Balloc(mhi->k);
|
|
3190
|
+
if (!mhi) goto nomem;
|
|
3165
3191
|
Bcopy(mhi, mlo);
|
|
3166
3192
|
mhi = lshift(mhi, Log2P);
|
|
3193
|
+
if (!mhi) goto nomem;
|
|
3167
3194
|
}
|
|
3168
3195
|
|
|
3169
3196
|
for (i = 1;;i++) {
|
|
@@ -3173,6 +3200,7 @@ one_digit:
|
|
|
3173
3200
|
*/
|
|
3174
3201
|
j = cmp(b, mlo);
|
|
3175
3202
|
delta = diff(S, mhi);
|
|
3203
|
+
if (!delta) goto nomem;
|
|
3176
3204
|
j1 = delta->sign ? 1 : cmp(b, delta);
|
|
3177
3205
|
Bfree(delta);
|
|
3178
3206
|
#ifndef ROUND_BIASED
|
|
@@ -3213,6 +3241,7 @@ one_digit:
|
|
|
3213
3241
|
#endif /*Honor_FLT_ROUNDS*/
|
|
3214
3242
|
if (j1 > 0) {
|
|
3215
3243
|
b = lshift(b, 1);
|
|
3244
|
+
if (!b) goto nomem;
|
|
3216
3245
|
j1 = cmp(b, S);
|
|
3217
3246
|
if ((j1 > 0 || (j1 == 0 && (dig & 1))) && dig++ == '9')
|
|
3218
3247
|
goto round_9_up;
|
|
@@ -3241,11 +3270,16 @@ keep_dig:
|
|
|
3241
3270
|
if (i == ilim)
|
|
3242
3271
|
break;
|
|
3243
3272
|
b = multadd(b, 10, 0);
|
|
3244
|
-
if (
|
|
3273
|
+
if (!b) goto nomem;
|
|
3274
|
+
if (mlo == mhi) {
|
|
3245
3275
|
mlo = mhi = multadd(mhi, 10, 0);
|
|
3276
|
+
if (!mlo) goto nomem;
|
|
3277
|
+
}
|
|
3246
3278
|
else {
|
|
3247
3279
|
mlo = multadd(mlo, 10, 0);
|
|
3280
|
+
if (!mlo) goto nomem;
|
|
3248
3281
|
mhi = multadd(mhi, 10, 0);
|
|
3282
|
+
if (!mhi) goto nomem;
|
|
3249
3283
|
}
|
|
3250
3284
|
}
|
|
3251
3285
|
}
|
|
@@ -3261,6 +3295,7 @@ keep_dig:
|
|
|
3261
3295
|
if (i >= ilim)
|
|
3262
3296
|
break;
|
|
3263
3297
|
b = multadd(b, 10, 0);
|
|
3298
|
+
if (!b) goto nomem;
|
|
3264
3299
|
}
|
|
3265
3300
|
|
|
3266
3301
|
/* Round off last digit */
|
|
@@ -3272,6 +3307,7 @@ keep_dig:
|
|
|
3272
3307
|
}
|
|
3273
3308
|
#endif
|
|
3274
3309
|
b = lshift(b, 1);
|
|
3310
|
+
if (!b) goto nomem;
|
|
3275
3311
|
j = cmp(b, S);
|
|
3276
3312
|
if (j > 0 || (j == 0 && (dig & 1))) {
|
|
3277
3313
|
roundoff:
|
|
@@ -3313,6 +3349,16 @@ ret1:
|
|
|
3313
3349
|
if (rve)
|
|
3314
3350
|
*rve = s;
|
|
3315
3351
|
return s0;
|
|
3352
|
+
nomem:
|
|
3353
|
+
if (S) Bfree(S);
|
|
3354
|
+
if (mhi) {
|
|
3355
|
+
if (mlo && mlo != mhi)
|
|
3356
|
+
Bfree(mlo);
|
|
3357
|
+
Bfree(mhi);
|
|
3358
|
+
}
|
|
3359
|
+
if (b) Bfree(b);
|
|
3360
|
+
FREE(s0);
|
|
3361
|
+
return NULL;
|
|
3316
3362
|
}
|
|
3317
3363
|
|
|
3318
3364
|
/*-
|
|
@@ -3421,6 +3467,7 @@ hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int *sign, char **rv
|
|
|
3421
3467
|
*/
|
|
3422
3468
|
bufsize = (ndigits > 0) ? ndigits : SIGFIGS;
|
|
3423
3469
|
s0 = rv_alloc(bufsize+1);
|
|
3470
|
+
if (!s0) return NULL;
|
|
3424
3471
|
|
|
3425
3472
|
/* Round to the desired number of digits. */
|
|
3426
3473
|
if (SIGFIGS > ndigits && ndigits > 0) {
|