166#ifdef WORDS_BIGENDIAN
167#define IEEE_BIG_ENDIAN
169#define IEEE_LITTLE_ENDIAN
174#undef IEEE_BIG_ENDIAN
175#undef IEEE_LITTLE_ENDIAN
178#if defined(__arm__) && !defined(__VFP_FP__)
179#define IEEE_BIG_ENDIAN
180#undef IEEE_LITTLE_ENDIAN
188#if (INT_MAX >> 30) && !(INT_MAX >> 31)
190#define ULong unsigned int
191#elif (LONG_MAX >> 30) && !(LONG_MAX >> 31)
193#define ULong unsigned long int
195#error No 32bit integer
199#define Llong LONG_LONG
206#define Bug(x) {fprintf(stderr, "%s\n", (x)); exit(EXIT_FAILURE);}
211#define ISDIGIT(c) isdigit(c)
222extern void *MALLOC(
size_t);
224#define MALLOC xmalloc
227extern void FREE(
void*);
232#define NO_SANITIZE(x, y) y
235#ifndef Omit_Private_Memory
237#define PRIVATE_MEM 2304
239#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
240static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
244#undef Avoid_Underflow
245#ifdef IEEE_BIG_ENDIAN
248#ifdef IEEE_LITTLE_ENDIAN
256#define DBL_MAX_10_EXP 308
257#define DBL_MAX_EXP 1024
263#define DBL_MAX_10_EXP 75
264#define DBL_MAX_EXP 63
266#define DBL_MAX 7.2370055773322621e+75
271#define DBL_MAX_10_EXP 38
272#define DBL_MAX_EXP 127
274#define DBL_MAX 1.7014118346046923e+38
278#define LONG_MAX 2147483647
295static const char hexdigit[] =
"0123456789abcdef0123456789ABCDEF";
298#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + defined(IBM) != 1
299Exactly one of IEEE_LITTLE_ENDIAN, IEEE_BIG_ENDIAN, VAX, or IBM should be defined.
302typedef union {
double d; ULong L[2]; }
U;
307# ifdef IEEE_LITTLE_ENDIAN
308# define word0(x) (((ULong *)&(x))[1])
309# define word1(x) (((ULong *)&(x))[0])
311# define word0(x) (((ULong *)&(x))[0])
312# define word1(x) (((ULong *)&(x))[1])
316# ifdef IEEE_LITTLE_ENDIAN
317# define word0(x) ((x).L[1])
318# define word1(x) ((x).L[0])
320# define word0(x) ((x).L[0])
321# define word1(x) ((x).L[1])
323# define dval(x) ((x).d)
330#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm__)
331#define Storeinc(a,b,c) (((unsigned short *)(a))[1] = (unsigned short)(b), \
332((unsigned short *)(a))[0] = (unsigned short)(c), (a)++)
334#define Storeinc(a,b,c) (((unsigned short *)(a))[0] = (unsigned short)(b), \
335((unsigned short *)(a))[1] = (unsigned short)(c), (a)++)
347#define Exp_msk1 0x100000
348#define Exp_msk11 0x100000
349#define Exp_mask 0x7ff00000
353#define Exp_1 0x3ff00000
354#define Exp_11 0x3ff00000
356#define Frac_mask 0xfffff
357#define Frac_mask1 0xfffff
360#define Bndry_mask 0xfffff
361#define Bndry_mask1 0xfffff
363#define Sign_bit 0x80000000
370#define Avoid_Underflow
372#undef Sudden_Underflow
378#define Flt_Rounds FLT_ROUNDS
384#ifdef Honor_FLT_ROUNDS
385#define Rounding rounding
386#undef Check_FLT_ROUNDS
387#define Check_FLT_ROUNDS
389#define Rounding Flt_Rounds
393#undef Check_FLT_ROUNDS
394#undef Honor_FLT_ROUNDS
396#undef Sudden_Underflow
397#define Sudden_Underflow
403#define Exp_msk1 0x1000000
404#define Exp_msk11 0x1000000
405#define Exp_mask 0x7f000000
408#define Exp_1 0x41000000
409#define Exp_11 0x41000000
411#define Frac_mask 0xffffff
412#define Frac_mask1 0xffffff
415#define Bndry_mask 0xefffff
416#define Bndry_mask1 0xffffff
418#define Sign_bit 0x80000000
420#define Tiny0 0x100000
430#define Exp_msk11 0x800000
431#define Exp_mask 0x7f80
434#define Exp_1 0x40800000
437#define Frac_mask 0x7fffff
438#define Frac_mask1 0xffff007f
441#define Bndry_mask 0xffff007f
442#define Bndry_mask1 0xffff007f
444#define Sign_bit 0x8000
458#define rounded_product(a,b) ((a) = rnd_prod((a), (b)))
459#define rounded_quotient(a,b) ((a) = rnd_quot((a), (b)))
460extern double rnd_prod(
double,
double), rnd_quot(
double,
double);
462#define rounded_product(a,b) ((a) *= (b))
463#define rounded_quotient(a,b) ((a) /= (b))
466#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
467#define Big1 0xffffffff
473#define FFFFFFFF 0xffffffffUL
487#define Llong long long
490#define ULLong unsigned Llong
494#define MULTIPLE_THREADS 1
496#ifndef MULTIPLE_THREADS
497#define ACQUIRE_DTOA_LOCK(n)
498#define FREE_DTOA_LOCK(n)
500#define ACQUIRE_DTOA_LOCK(n)
501#define FREE_DTOA_LOCK(n)
504#ifndef ATOMIC_PTR_CAS
505#define ATOMIC_PTR_CAS(var, old, new) ((var) = (new), (old))
511#define UNLIKELY(x) (x)
514#define ASSUME(x) (void)(x)
521 int k, maxwds, sign, wds;
527static Bigint *freelist[Kmax+1];
529#define BLOCKING_BIGINT ((Bigint *)(-1))
536#ifndef Omit_Private_Memory
541 ACQUIRE_DTOA_LOCK(0);
546 rv = ATOMIC_PTR_CAS(freelist[k], rv, BLOCKING_BIGINT);
547 if (LIKELY(rv != BLOCKING_BIGINT && rvn == rv)) {
548 rvn = ATOMIC_PTR_CAS(freelist[k], BLOCKING_BIGINT, rv->next);
549 assert(rvn == BLOCKING_BIGINT);
557#ifdef Omit_Private_Memory
558 rv = (
Bigint *)MALLOC(
sizeof(
Bigint) + (x-1)*
sizeof(ULong));
560 len = (
sizeof(
Bigint) + (x-1)*
sizeof(ULong) +
sizeof(
double) - 1)
563 double *pnext = pmem_next;
564 while (pnext - private_mem + len <= PRIVATE_mem) {
566 pnext = ATOMIC_PTR_CAS(pmem_next, pnext, pnext + len);
567 if (LIKELY(p == pnext)) {
575 rv = (
Bigint*)MALLOC(len*
sizeof(
double));
581 rv->sign = rv->wds = 0;
594 ACQUIRE_DTOA_LOCK(0);
597 vn = ATOMIC_PTR_CAS(freelist[v->k], 0, 0);
598 }
while (UNLIKELY(vn == BLOCKING_BIGINT));
600 }
while (UNLIKELY(ATOMIC_PTR_CAS(freelist[v->k], vn, v) != vn));
605#define Bcopy(x,y) memcpy((char *)&(x)->sign, (char *)&(y)->sign, \
606(y)->wds*sizeof(Long) + 2*sizeof(int))
609multadd(
Bigint *b,
int m,
int a)
629 y = *x * (ULLong)m + carry;
631 *x++ = (ULong)(y & FFFFFFFF);
635 y = (xi & 0xffff) * m + carry;
636 z = (xi >> 16) * m + (y >> 16);
638 *x++ = (z << 16) + (y & 0xffff);
647 if (wds >= b->maxwds) {
653 b->x[wds++] = (ULong)carry;
660s2b(
const char *s,
int nd0,
int nd, ULong y9)
667 for (k = 0, y = 1; x > y; y <<= 1, k++) ;
674 b->x[0] = y9 & 0xffff;
675 b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
682 b = multadd(b, 10, *s++ -
'0');
689 b = multadd(b, 10, *s++ -
'0');
694hi0bits(
register ULong x)
698 if (!(x & 0xffff0000)) {
702 if (!(x & 0xff000000)) {
706 if (!(x & 0xf0000000)) {
710 if (!(x & 0xc0000000)) {
714 if (!(x & 0x80000000)) {
716 if (!(x & 0x40000000))
726 register ULong x = *y;
781 ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
792 if (a->wds < b->wds) {
804 for (x = c->x, xa = x + wc; x < xa; x++)
812 for (; xb < xbe; xc0++) {
813 if ((y = *xb++) != 0) {
818 z = *x++ * (ULLong)y + *xc + carry;
820 *xc++ = (ULong)(z & FFFFFFFF);
827 for (; xb < xbe; xb++, xc0++) {
828 if ((y = *xb & 0xffff) != 0) {
833 z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
835 z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
841 if ((y = *xb >> 16) != 0) {
847 z = (*x & 0xffff) * y + (*xc >> 16) + carry;
850 z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
857 for (; xb < xbe; xc0++) {
863 z = *x++ * y + *xc + carry;
872 for (xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
885 static const int p05[3] = { 5, 25, 125 };
887 if ((i = k & 3) != 0)
888 b = multadd(b, p05[i-1], 0);
894 ACQUIRE_DTOA_LOCK(1);
898 p5tmp = ATOMIC_PTR_CAS(p5s, NULL, p5);
899 if (UNLIKELY(p5tmp)) {
914 if (!(p51 = p5->next)) {
915 ACQUIRE_DTOA_LOCK(1);
916 if (!(p51 = p5->next)) {
919 p5tmp = ATOMIC_PTR_CAS(p5->next, NULL, p51);
920 if (UNLIKELY(p5tmp)) {
937 ULong *x, *x1, *xe, z;
946 for (i = b->maxwds; n1 > i; i <<= 1)
950 for (i = 0; i < n; i++)
970 *x1++ = *x << k & 0xffff | z;
989 ULong *xa, *xa0, *xb, *xb0;
995 if (i > 1 && !a->x[i-1])
996 Bug(
"cmp called with a->x[a->wds-1] == 0");
997 if (j > 1 && !b->x[j-1])
998 Bug(
"cmp called with b->x[b->wds-1] == 0");
1008 return *xa < *xb ? -1 : 1;
1021 ULong *xa, *xae, *xb, *xbe, *xc;
1058 y = (ULLong)*xa++ - *xb++ - borrow;
1059 borrow = y >> 32 & (ULong)1;
1060 *xc++ = (ULong)(y & FFFFFFFF);
1064 borrow = y >> 32 & (ULong)1;
1065 *xc++ = (ULong)(y & FFFFFFFF);
1070 y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
1071 borrow = (y & 0x10000) >> 16;
1072 z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
1073 borrow = (z & 0x10000) >> 16;
1077 y = (*xa & 0xffff) - borrow;
1078 borrow = (y & 0x10000) >> 16;
1079 z = (*xa++ >> 16) - borrow;
1080 borrow = (z & 0x10000) >> 16;
1085 y = *xa++ - *xb++ - borrow;
1086 borrow = (y & 0x10000) >> 16;
1091 borrow = (y & 0x10000) >> 16;
1109 L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
1110#ifndef Avoid_Underflow
1111#ifndef Sudden_Underflow
1120#ifndef Avoid_Underflow
1121#ifndef Sudden_Underflow
1124 L = -L >> Exp_shift;
1125 if (L < Exp_shift) {
1126 word0(a) = 0x80000 >> L;
1132 word1(a) = L >= 31 ? 1 : 1 << 31 - L;
1143 ULong *xa, *xa0, w, y, z;
1157 if (!y) Bug(
"zero y in b2d");
1163 d0 = Exp_1 | y >> (Ebits - k);
1164 w = xa > xa0 ? *--xa : 0;
1165 d1 = y << ((32-Ebits) + k) | w >> (Ebits - k);
1168 z = xa > xa0 ? *--xa : 0;
1170 d0 = Exp_1 | y << k | z >> (32 - k);
1171 y = xa > xa0 ? *--xa : 0;
1172 d1 = z << k | y >> (32 - k);
1179 if (k < Ebits + 16) {
1180 z = xa > xa0 ? *--xa : 0;
1181 d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
1182 w = xa > xa0 ? *--xa : 0;
1183 y = xa > xa0 ? *--xa : 0;
1184 d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
1187 z = xa > xa0 ? *--xa : 0;
1188 w = xa > xa0 ? *--xa : 0;
1190 d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
1191 y = xa > xa0 ? *--xa : 0;
1192 d1 = w << k + 16 | y << k;
1196 word0(d) = d0 >> 16 | d0 << 16;
1197 word1(d) = d1 >> 16 | d1 << 16;
1206d2b(
double d_,
int *e,
int *bits)
1212#ifndef Sudden_Underflow
1220 d0 = word0(d) >> 16 | word0(d) << 16;
1221 d1 = word1(d) >> 16 | word1(d) << 16;
1236#ifdef Sudden_Underflow
1237 de = (int)(d0 >> Exp_shift);
1242 if ((de = (
int)(d0 >> Exp_shift)) != 0)
1246 if ((y = d1) != 0) {
1247 if ((k = lo0bits(&y)) != 0) {
1248 x[0] = y | z << (32 - k);
1253#ifndef Sudden_Underflow
1256 b->wds = (x[1] = z) ? 2 : 1;
1261 Bug(
"Zero passed to d2b");
1265#ifndef Sudden_Underflow
1273 if (k = lo0bits(&y))
1275 x[0] = y | z << 32 - k & 0xffff;
1276 x[1] = z >> k - 16 & 0xffff;
1282 x[1] = y >> 16 | z << 16 - k & 0xffff;
1283 x[2] = z >> k & 0xffff;
1298 Bug(
"Zero passed to d2b");
1316#ifndef Sudden_Underflow
1320 *e = (de - Bias - (P-1) << 2) + k;
1321 *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
1323 *e = de - Bias - (P-1) + k;
1326#ifndef Sudden_Underflow
1329 *e = de - Bias - (P-1) + 1 + k;
1331 *bits = 32*i - hi0bits(x[i-1]);
1333 *bits = (i+2)*16 - hi0bits(x[i]);
1348 dval(da) = b2d(a, &ka);
1349 dval(db) = b2d(b, &kb);
1351 k = ka - kb + 32*(a->wds - b->wds);
1353 k = ka - kb + 16*(a->wds - b->wds);
1357 word0(da) += (k >> 2)*Exp_msk1;
1363 word0(db) += (k >> 2)*Exp_msk1;
1369 word0(da) += k*Exp_msk1;
1372 word0(db) += k*Exp_msk1;
1375 return dval(da) / dval(db);
1380 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1381 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
1390bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
1391static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
1392#ifdef Avoid_Underflow
1393 9007199254740992.*9007199254740992.e-256
1401#define Scale_Bit 0x10
1405bigtens[] = { 1e16, 1e32, 1e64 };
1406static const double tinytens[] = { 1e-16, 1e-32, 1e-64 };
1409bigtens[] = { 1e16, 1e32 };
1410static const double tinytens[] = { 1e-16, 1e-32 };
1422#define NAN_WORD0 0x7ff80000
1430match(
const char **sp,
char *t)
1433 const char *s = *sp;
1436 if ((c = *++s) >=
'A' && c <=
'Z')
1447hexnan(
double *rvp,
const char **sp)
1451 int havedig, udx0, xshift;
1454 havedig = xshift = 0;
1457 while (c = *(
const unsigned char*)++s) {
1458 if (c >=
'0' && c <=
'9')
1460 else if (c >=
'a' && c <=
'f')
1462 else if (c >=
'A' && c <=
'F')
1464 else if (c <=
' ') {
1465 if (udx0 && havedig) {
1471 else if ( c ==
')' && havedig) {
1484 x[0] = (x[0] << 4) | (x[1] >> 28);
1485 x[1] = (x[1] << 4) | c;
1487 if ((x[0] &= 0xfffff) || x[1]) {
1488 word0(*rvp) = Exp_mask | x[0];
1495NO_SANITIZE(
"unsigned-integer-overflow",
double strtod(
const char *s00,
char **se));
1497strtod(
const char *s00,
char **se)
1499#ifdef Avoid_Underflow
1502 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
1503 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
1504 const char *s, *s0, *s1;
1509 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
1511 int inexact, oldinexact;
1513#ifdef Honor_FLT_ROUNDS
1521 sign = nz0 = nz = 0;
1546 if (s[1] ==
'x' || s[1] ==
'X') {
1552 if (!*++s || !(s1 = strchr(hexdigit, *s)))
goto ret0;
1554 while (*++s ==
'0');
1556 s1 = strchr(hexdigit, *s);
1560 adj += aadj * ((s1 - hexdigit) & 15);
1563 }
while (*++s && (s1 = strchr(hexdigit, *s)));
1568 if (!*++s || !(s1 = strchr(hexdigit, *s)))
goto ret0;
1575 for (; *s && (s1 = strchr(hexdigit, *s)); ++s) {
1576 adj += aadj * ((s1 - hexdigit) & 15);
1577 if ((aadj /= 16) == 0.0) {
1578 while (*++s && strchr(hexdigit, *s));
1587 if (*s ==
'P' || *s ==
'p') {
1588 dsign = 0x2C - *++s;
1589 if (abs(dsign) == 1) s++;
1594 if (c <
'0' ||
'9' < c)
goto ret0;
1601 if (nd + dsign * nd0 > 2095) {
1602 while (
'0' <= c && c <=
'9') c = *++s;
1605 }
while (
'0' <= c && c <=
'9');
1609 if (dsign)
goto ret0;
1611 dval(rv) = ldexp(adj, nd0);
1615 while (*++s ==
'0') ;
1621 for (nd = nf = 0; (c = *s) >=
'0' && c <=
'9'; nd++, s++)
1624 else if (nd < DBL_DIG + 2)
1628 s1 = localeconv()->decimal_point;
1651 for (; c ==
'0'; c = *++s)
1653 if (c >
'0' && c <=
'9') {
1661 for (; c >=
'0' && c <=
'9'; c = *++s) {
1664 if (nd > DBL_DIG * 4) {
1669 for (i = 1; i < nz; i++)
1672 else if (nd <= DBL_DIG + 2)
1676 else if (nd <= DBL_DIG + 2)
1684 if (c ==
'e' || c ==
'E') {
1685 if (!nd && !nz && !nz0) {
1696 if (c >=
'0' && c <=
'9') {
1699 if (c >
'0' && c <=
'9') {
1702 while ((c = *++s) >=
'0' && c <=
'9')
1704 if (s - s1 > 8 || L > 19999)
1727 if (match(&s,
"nf")) {
1729 if (!match(&s,
"inity"))
1731 word0(rv) = 0x7ff00000;
1738 if (match(&s,
"an")) {
1739 word0(rv) = NAN_WORD0;
1740 word1(rv) = NAN_WORD1;
1764 k = nd < DBL_DIG + 2 ? nd : DBL_DIG + 2;
1769 oldinexact = get_inexact();
1771 dval(rv) = tens[k - 9] * dval(rv) + z;
1773 bd0 = bb = bd = bs = delta = 0;
1776#ifndef Honor_FLT_ROUNDS
1784 if (e <= Ten_pmax) {
1786 goto vax_ovfl_check;
1788#ifdef Honor_FLT_ROUNDS
1791 dval(rv) = -dval(rv);
1795 rounded_product(dval(rv), tens[e]);
1800 if (e <= Ten_pmax + i) {
1804#ifdef Honor_FLT_ROUNDS
1807 dval(rv) = -dval(rv);
1812 dval(rv) *= tens[i];
1818 word0(rv) -= P*Exp_msk1;
1819 rounded_product(dval(rv), tens[e]);
1820 if ((word0(rv) & Exp_mask)
1821 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
1823 word0(rv) += P*Exp_msk1;
1825 rounded_product(dval(rv), tens[e]);
1830#ifndef Inaccurate_Divide
1831 else if (e >= -Ten_pmax) {
1832#ifdef Honor_FLT_ROUNDS
1835 dval(rv) = -dval(rv);
1839 rounded_quotient(dval(rv), tens[-e]);
1850 oldinexact = get_inexact();
1852#ifdef Avoid_Underflow
1855#ifdef Honor_FLT_ROUNDS
1856 if ((rounding = Flt_Rounds) >= 2) {
1858 rounding = rounding == 2 ? 0 : 2;
1869 if ((i = e1 & 15) != 0)
1870 dval(rv) *= tens[i];
1872 if (e1 > DBL_MAX_10_EXP) {
1879#ifdef Honor_FLT_ROUNDS
1887 word0(rv) = Exp_mask;
1891 word0(rv) = Exp_mask;
1897 dval(rv0) *= dval(rv0);
1908 for (j = 0; e1 > 1; j++, e1 >>= 1)
1910 dval(rv) *= bigtens[j];
1912 word0(rv) -= P*Exp_msk1;
1913 dval(rv) *= bigtens[j];
1914 if ((z = word0(rv) & Exp_mask)
1915 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
1917 if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
1924 word0(rv) += P*Exp_msk1;
1929 if ((i = e1 & 15) != 0)
1930 dval(rv) /= tens[i];
1932 if (e1 >= 1 << n_bigtens)
1934#ifdef Avoid_Underflow
1937 for (j = 0; e1 > 0; j++, e1 >>= 1)
1939 dval(rv) *= tinytens[j];
1940 if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask)
1941 >> Exp_shift)) > 0) {
1946 word0(rv) = (P+2)*Exp_msk1;
1948 word0(rv) &= 0xffffffff << (j-32);
1951 word1(rv) &= 0xffffffff << j;
1954 for (j = 0; e1 > 1; j++, e1 >>= 1)
1956 dval(rv) *= tinytens[j];
1958 dval(rv0) = dval(rv);
1959 dval(rv) *= tinytens[j];
1961 dval(rv) = 2.*dval(rv0);
1962 dval(rv) *= tinytens[j];
1974#ifndef Avoid_Underflow
1989 bd0 = s2b(s0, nd0, nd, y);
1992 bd = Balloc(bd0->k);
1994 bb = d2b(dval(rv), &bbe, &bbbits);
2010#ifdef Honor_FLT_ROUNDS
2014#ifdef Avoid_Underflow
2022#ifdef Sudden_Underflow
2024 j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
2039#ifdef Avoid_Underflow
2042 i = bb2 < bd2 ? bb2 : bd2;
2051 bs = pow5mult(bs, bb5);
2057 bb = lshift(bb, bb2);
2059 bd = pow5mult(bd, bd5);
2061 bd = lshift(bd, bd2);
2063 bs = lshift(bs, bs2);
2064 delta = diff(bb, bd);
2065 dsign = delta->sign;
2068#ifdef Honor_FLT_ROUNDS
2069 if (rounding != 1) {
2072 if (!delta->x[0] && delta->wds <= 1) {
2088 && !(word0(rv) & Frac_mask)) {
2089 y = word0(rv) & Exp_mask;
2090#ifdef Avoid_Underflow
2091 if (!scale || y > 2*P*Exp_msk1)
2096 delta = lshift(delta,Log2P);
2097 if (cmp(delta, bs) <= 0)
2102#ifdef Avoid_Underflow
2103 if (scale && (y = word0(rv) & Exp_mask)
2105 word0(adj) += (2*P+1)*Exp_msk1 - y;
2107#ifdef Sudden_Underflow
2108 if ((word0(rv) & Exp_mask) <=
2110 word0(rv) += P*Exp_msk1;
2111 dval(rv) += adj*ulp(dval(rv));
2112 word0(rv) -= P*Exp_msk1;
2117 dval(rv) += adj*ulp(dval(rv));
2121 adj = ratio(delta, bs);
2124 if (adj <= 0x7ffffffe) {
2128 if (!((rounding>>1) ^ dsign))
2133#ifdef Avoid_Underflow
2134 if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
2135 word0(adj) += (2*P+1)*Exp_msk1 - y;
2137#ifdef Sudden_Underflow
2138 if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
2139 word0(rv) += P*Exp_msk1;
2140 adj *= ulp(dval(rv));
2145 word0(rv) -= P*Exp_msk1;
2150 adj *= ulp(dval(rv));
2163 if (dsign || word1(rv) || word0(rv) & Bndry_mask
2165#ifdef Avoid_Underflow
2166 || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1
2168 || (word0(rv) & Exp_mask) <= Exp_msk1
2173 if (!delta->x[0] && delta->wds <= 1)
2178 if (!delta->x[0] && delta->wds <= 1) {
2185 delta = lshift(delta,Log2P);
2186 if (cmp(delta, bs) > 0)
2193 if ((word0(rv) & Bndry_mask1) == Bndry_mask1
2195#ifdef Avoid_Underflow
2196 (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
2197 ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :
2201 word0(rv) = (word0(rv) & Exp_mask)
2208#ifdef Avoid_Underflow
2214 else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
2217#ifdef Sudden_Underflow
2218 L = word0(rv) & Exp_mask;
2222#ifdef Avoid_Underflow
2223 if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1))
2231#ifdef Avoid_Underflow
2233 L = word0(rv) & Exp_mask;
2234 if (L <= (2*P+1)*Exp_msk1) {
2235 if (L > (P+2)*Exp_msk1)
2244 L = (word0(rv) & Exp_mask) - Exp_msk1;
2246 word0(rv) = L | Bndry_mask1;
2247 word1(rv) = 0xffffffff;
2255 if (!(word1(rv) & LSB))
2259 dval(rv) += ulp(dval(rv));
2262 dval(rv) -= ulp(dval(rv));
2263#ifndef Sudden_Underflow
2268#ifdef Avoid_Underflow
2274 if ((aadj = ratio(delta, bs)) <= 2.) {
2276 aadj = dval(aadj1) = 1.;
2277 else if (word1(rv) || word0(rv) & Bndry_mask) {
2278#ifndef Sudden_Underflow
2279 if (word1(rv) == Tiny1 && !word0(rv))
2289 if (aadj < 2./FLT_RADIX)
2290 aadj = 1./FLT_RADIX;
2293 dval(aadj1) = -aadj;
2298 dval(aadj1) = dsign ? aadj : -aadj;
2299#ifdef Check_FLT_ROUNDS
2309 if (Flt_Rounds == 0)
2313 y = word0(rv) & Exp_mask;
2317 if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
2318 dval(rv0) = dval(rv);
2319 word0(rv) -= P*Exp_msk1;
2320 adj = dval(aadj1) * ulp(dval(rv));
2322 if ((word0(rv) & Exp_mask) >=
2323 Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
2324 if (word0(rv0) == Big0 && word1(rv0) == Big1)
2331 word0(rv) += P*Exp_msk1;
2334#ifdef Avoid_Underflow
2335 if (scale && y <= 2*P*Exp_msk1) {
2336 if (aadj <= 0x7fffffff) {
2337 if ((z = (
int)aadj) <= 0)
2340 dval(aadj1) = dsign ? aadj : -aadj;
2342 word0(aadj1) += (2*P+1)*Exp_msk1 - y;
2344 adj = dval(aadj1) * ulp(dval(rv));
2347#ifdef Sudden_Underflow
2348 if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
2349 dval(rv0) = dval(rv);
2350 word0(rv) += P*Exp_msk1;
2351 adj = dval(aadj1) * ulp(dval(rv));
2354 if ((word0(rv) & Exp_mask) < P*Exp_msk1)
2356 if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
2359 if (word0(rv0) == Tiny0 && word1(rv0) == Tiny1)
2366 word0(rv) -= P*Exp_msk1;
2369 adj = dval(aadj1) * ulp(dval(rv));
2380 if (y <= (P-1)*Exp_msk1 && aadj > 1.) {
2381 dval(aadj1) = (double)(
int)(aadj + 0.5);
2383 dval(aadj1) = -dval(aadj1);
2385 adj = dval(aadj1) * ulp(dval(rv));
2390 z = word0(rv) & Exp_mask;
2392#ifdef Avoid_Underflow
2400 if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
2401 if (aadj < .4999999 || aadj > .5000001)
2404 else if (aadj < .4999999/FLT_RADIX)
2417 word0(rv0) = Exp_1 + (70 << Exp_shift);
2422 else if (!oldinexact)
2425#ifdef Avoid_Underflow
2427 word0(rv0) = Exp_1 - 2*P*Exp_msk1;
2429 dval(rv) *= dval(rv0);
2432 if (word0(rv) == 0 && word1(rv) == 0)
2438 if (inexact && !(word0(rv) & Exp_mask)) {
2441 dval(rv0) *= dval(rv0);
2453 return sign ? -dval(rv) : dval(rv);
2456NO_SANITIZE(
"unsigned-integer-overflow",
static int quorem(
Bigint *b,
Bigint *S));
2461 ULong *bx, *bxe, q, *sx, *sxe;
2463 ULLong borrow, carry, y, ys;
2465 ULong borrow, carry, y, ys;
2474 Bug(
"oversize b in quorem");
2482 q = *bxe / (*sxe + 1);
2485 Bug(
"oversized quotient in quorem");
2492 ys = *sx++ * (ULLong)q + carry;
2494 y = *bx - (ys & FFFFFFFF) - borrow;
2495 borrow = y >> 32 & (ULong)1;
2496 *bx++ = (ULong)(y & FFFFFFFF);
2500 ys = (si & 0xffff) * q + carry;
2501 zs = (si >> 16) * q + (ys >> 16);
2503 y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
2504 borrow = (y & 0x10000) >> 16;
2505 z = (*bx >> 16) - (zs & 0xffff) - borrow;
2506 borrow = (z & 0x10000) >> 16;
2509 ys = *sx++ * q + carry;
2511 y = *bx - (ys & 0xffff) - borrow;
2512 borrow = (y & 0x10000) >> 16;
2516 }
while (sx <= sxe);
2519 while (--bxe > bx && !*bxe)
2524 if (cmp(b, S) >= 0) {
2534 y = *bx - (ys & FFFFFFFF) - borrow;
2535 borrow = y >> 32 & (ULong)1;
2536 *bx++ = (ULong)(y & FFFFFFFF);
2540 ys = (si & 0xffff) + carry;
2541 zs = (si >> 16) + (ys >> 16);
2543 y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
2544 borrow = (y & 0x10000) >> 16;
2545 z = (*bx >> 16) - (zs & 0xffff) - borrow;
2546 borrow = (z & 0x10000) >> 16;
2551 y = *bx - (ys & 0xffff) - borrow;
2552 borrow = (y & 0x10000) >> 16;
2556 }
while (sx <= sxe);
2560 while (--bxe > bx && !*bxe)
2568#ifndef MULTIPLE_THREADS
2569static char *dtoa_result;
2572#ifndef MULTIPLE_THREADS
2576 return dtoa_result = MALLOC(i);
2579#define rv_alloc(i) MALLOC(i)
2583nrv_alloc(
const char *s,
char **rve,
size_t n)
2587 t = rv = rv_alloc(n);
2588 while ((*t = *s++) != 0) t++;
2594#define rv_strdup(s, rve) nrv_alloc((s), (rve), strlen(s)+1)
2596#ifndef MULTIPLE_THREADS
2610static const char INFSTR[] =
"Infinity";
2611static const char NANSTR[] =
"NaN";
2612static const char ZEROSTR[] =
"0";
2649dtoa(
double d_,
int mode,
int ndigits,
int *decpt,
int *sign,
char **rve)
2685 int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
2686 j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
2687 spec_case, try_quick, half = 0;
2689#ifndef Sudden_Underflow
2693 Bigint *b, *b1, *delta, *mlo = 0, *mhi = 0, *S;
2697#ifdef Honor_FLT_ROUNDS
2701 int inexact, oldinexact;
2706#ifndef MULTIPLE_THREADS
2708 freedtoa(dtoa_result);
2713 if (word0(d) & Sign_bit) {
2716 word0(d) &= ~Sign_bit;
2721#if defined(IEEE_Arith) + defined(VAX)
2723 if ((word0(d) & Exp_mask) == Exp_mask)
2725 if (word0(d) == 0x8000)
2731 if (!word1(d) && !(word0(d) & 0xfffff))
2732 return rv_strdup(INFSTR, rve);
2734 return rv_strdup(NANSTR, rve);
2742 return rv_strdup(ZEROSTR, rve);
2746 try_quick = oldinexact = get_inexact();
2749#ifdef Honor_FLT_ROUNDS
2750 if ((rounding = Flt_Rounds) >= 2) {
2752 rounding = rounding == 2 ? 0 : 2;
2759 b = d2b(dval(d), &be, &bbits);
2760#ifdef Sudden_Underflow
2761 i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
2763 if ((i = (
int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) {
2766 word0(d2) &= Frac_mask1;
2767 word0(d2) |= Exp_11;
2769 if (j = 11 - hi0bits(word0(d2) & Frac_mask))
2800#ifndef Sudden_Underflow
2806 i = bbits + be + (Bias + (P-1) - 1);
2807 x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32)
2808 : word1(d) << (32 - i);
2810 word0(d2) -= 31*Exp_msk1;
2811 i -= (Bias + (P-1) - 1) + 1;
2815 ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
2817 if (ds < 0. && ds != k)
2820 if (k >= 0 && k <= Ten_pmax) {
2821 if (dval(d) < tens[k])
2844 if (mode < 0 || mode > 9)
2848#ifdef Check_FLT_ROUNDS
2849 try_quick = Rounding == 1;
2873 ilim = ilim1 = i = ndigits;
2879 i = ndigits + k + 1;
2885 s = s0 = rv_alloc(i+1);
2887#ifdef Honor_FLT_ROUNDS
2888 if (mode > 1 && rounding != 1)
2892 if (ilim >= 0 && ilim <= Quick_max && try_quick) {
2907 dval(d) /= bigtens[n_bigtens-1];
2910 for (; j; j >>= 1, i++)
2917 else if ((j1 = -k) != 0) {
2918 dval(d) *= tens[j1 & 0xf];
2919 for (j = j1 >> 4; j; j >>= 1, i++)
2922 dval(d) *= bigtens[i];
2925 if (k_check && dval(d) < 1. && ilim > 0) {
2933 dval(eps) = ieps*dval(d) + 7.;
2934 word0(eps) -= (P-1)*Exp_msk1;
2938 if (dval(d) > dval(eps))
2940 if (dval(d) < -dval(eps))
2949 dval(eps) = 0.5/tens[ilim-1] - dval(eps);
2953 *s++ =
'0' + (int)L;
2954 if (dval(d) < dval(eps))
2956 if (1. - dval(d) < dval(eps))
2967 dval(eps) *= tens[ilim-1];
2968 for (i = 1;; i++, dval(d) *= 10.) {
2969 L = (Long)(dval(d));
2970 if (!(dval(d) -= L))
2972 *s++ =
'0' + (int)L;
2974 if (dval(d) > 0.5 + dval(eps))
2976 else if (dval(d) < 0.5 - dval(eps)) {
2977 while (*--s ==
'0') ;
2982 if ((*(s-1) -
'0') & 1) {
3000 if (be >= 0 && k <= Int_max) {
3003 if (ndigits < 0 && ilim <= 0) {
3005 if (ilim < 0 || dval(d) <= 5*ds)
3009 for (i = 1;; i++, dval(d) *= 10.) {
3010 L = (Long)(dval(d) / ds);
3012#ifdef Check_FLT_ROUNDS
3019 *s++ =
'0' + (int)L;
3027#ifdef Honor_FLT_ROUNDS
3031 case 2:
goto bump_up;
3035 if (dval(d) > ds || (dval(d) == ds && (L & 1))) {
3055#ifndef Sudden_Underflow
3056 denorm ? be + (Bias + (P-1) - 1 + 1) :
3059 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
3067 if (m2 > 0 && s2 > 0) {
3068 i = m2 < s2 ? m2 : s2;
3076 mhi = pow5mult(mhi, m5);
3081 if ((j = b5 - m5) != 0)
3085 b = pow5mult(b, b5);
3089 S = pow5mult(S, s5);
3094 if ((mode < 2 || leftright)
3095#ifdef Honor_FLT_ROUNDS
3099 if (!word1(d) && !(word0(d) & Bndry_mask)
3100#ifndef Sudden_Underflow
3101 && word0(d) & (Exp_mask & ~Exp_msk1)
3119 if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0)
3122 if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) != 0)
3144 b = multadd(b, 10, 0);
3146 mhi = multadd(mhi, 10, 0);
3150 if (ilim <= 0 && (mode == 3 || mode == 5)) {
3151 if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
3164 mhi = lshift(mhi, m2);
3172 mhi = Balloc(mhi->k);
3174 mhi = lshift(mhi, Log2P);
3178 dig = quorem(b,S) +
'0';
3183 delta = diff(S, mhi);
3184 j1 = delta->sign ? 1 : cmp(b, delta);
3187 if (j1 == 0 && mode != 1 && !(word1(d) & 1)
3188#ifdef Honor_FLT_ROUNDS
3197 else if (!b->x[0] && b->wds <= 1)
3204 if (j < 0 || (j == 0 && mode != 1
3209 if (!b->x[0] && b->wds <= 1) {
3215#ifdef Honor_FLT_ROUNDS
3218 case 0:
goto accept_dig;
3219 case 2:
goto keep_dig;
3225 if ((j1 > 0 || (j1 == 0 && (dig & 1))) && dig++ ==
'9')
3233#ifdef Honor_FLT_ROUNDS
3245#ifdef Honor_FLT_ROUNDS
3251 b = multadd(b, 10, 0);
3253 mlo = mhi = multadd(mhi, 10, 0);
3255 mlo = multadd(mlo, 10, 0);
3256 mhi = multadd(mhi, 10, 0);
3262 *s++ = dig = quorem(b,S) +
'0';
3263 if (!b->x[0] && b->wds <= 1) {
3271 b = multadd(b, 10, 0);
3276#ifdef Honor_FLT_ROUNDS
3278 case 0:
goto trimzeros;
3279 case 2:
goto roundoff;
3284 if (j > 0 || (j == 0 && (dig & 1))) {
3292 if (!half || (*s -
'0') & 1)
3296 while (*--s ==
'0') ;
3302 if (mlo && mlo != mhi)
3310 word0(d) = Exp_1 + (70 << Exp_shift);
3315 else if (!oldinexact)
3352#define DBL_MANH_SIZE 20
3353#define DBL_MANL_SIZE 32
3354#define DBL_ADJ (DBL_MAX_EXP - 2)
3355#define SIGFIGS ((DBL_MANT_DIG + 3) / 4 + 1)
3356#define dexp_get(u) ((int)(word0(u) >> Exp_shift) & ~Exp_msk1)
3357#define dexp_set(u,v) (word0(u) = (((int)(word0(u)) & ~Exp_mask) | ((v) << Exp_shift)))
3358#define dmanh_get(u) ((uint32_t)(word0(u) & Frac_mask))
3359#define dmanl_get(u) ((uint32_t)word1(u))
3387hdtoa(
double d,
const char *xdigs,
int ndigits,
int *decpt,
int *sign,
char **rve)
3392 uint32_t manh, manl;
3395 if (word0(u) & Sign_bit) {
3398 word0(u) &= ~Sign_bit;
3405 return rv_strdup(INFSTR, rve);
3407 else if (isnan(d)) {
3409 return rv_strdup(NANSTR, rve);
3411 else if (d == 0.0) {
3413 return rv_strdup(ZEROSTR, rve);
3415 else if (dexp_get(u)) {
3416 *decpt = dexp_get(u) - DBL_ADJ;
3419 u.d *= 5.363123171977039e+154 ;
3420 *decpt = dexp_get(u) - (514 + DBL_ADJ);
3430 bufsize = (ndigits > 0) ? ndigits : SIGFIGS;
3431 s0 = rv_alloc(bufsize+1);
3434 if (SIGFIGS > ndigits && ndigits > 0) {
3436 int offset = 4 * ndigits + DBL_MAX_EXP - 4 - DBL_MANT_DIG;
3437 dexp_set(u, offset);
3440 *decpt += dexp_get(u) - offset;
3443 manh = dmanh_get(u);
3444 manl = dmanl_get(u);
3446 for (s = s0 + 1; s < s0 + bufsize; s++) {
3447 *s = xdigs[(manh >> (DBL_MANH_SIZE - 4)) & 0xf];
3448 manh = (manh << 4) | (manl >> (DBL_MANL_SIZE - 4));
3454 for (ndigits = SIGFIGS; s0[ndigits - 1] ==
'0'; ndigits--)
#define ISDIGIT
Old name of rb_isdigit.
#define ASSUME
Old name of RBIMPL_ASSUME.
#define strtod(s, e)
Just another name of ruby_strtod.