155#ifdef WORDS_BIGENDIAN
156#define IEEE_BIG_ENDIAN
158#define IEEE_LITTLE_ENDIAN
163#undef IEEE_BIG_ENDIAN
164#undef IEEE_LITTLE_ENDIAN
167#if defined(__arm__) && !defined(__VFP_FP__)
168#define IEEE_BIG_ENDIAN
169#undef IEEE_LITTLE_ENDIAN
180#if (INT_MAX >> 30) && !(INT_MAX >> 31)
182#define ULong unsigned int
183#elif (LONG_MAX >> 30) && !(LONG_MAX >> 31)
185#define ULong unsigned long int
187#error No 32bit integer
190#if defined(HAVE_LONG_LONG) && (HAVE_LONG_LONG)
191#define Llong LONG_LONG
198#define Bug(x) {fprintf(stderr, "%s\n", (x)); exit(EXIT_FAILURE);}
203#define ISDIGIT(c) isdigit(c)
213#if defined(HAVE_STDCKDINT_H) || !defined(__has_include)
214#elif __has_include(<stdckdint.h>)
215# define HAVE_STDCKDINT_H 1
217#ifdef HAVE_STDCKDINT_H
218# include <stdckdint.h>
223ckd_add(
int *result,
int x,
int y)
226 if (y < INT_MIN - x)
return 1;
229 if (y > INT_MAX - x)
return 1;
237extern void *MALLOC(
size_t);
242extern void FREE(
void*);
247#define NO_SANITIZE(x, y) y
251#undef Avoid_Underflow
252#ifdef IEEE_BIG_ENDIAN
255#ifdef IEEE_LITTLE_ENDIAN
263#define DBL_MAX_10_EXP 308
264#define DBL_MAX_EXP 1024
270#define DBL_MAX_10_EXP 75
271#define DBL_MAX_EXP 63
273#define DBL_MAX 7.2370055773322621e+75
278#define DBL_MAX_10_EXP 38
279#define DBL_MAX_EXP 127
281#define DBL_MAX 1.7014118346046923e+38
285#define LONG_MAX 2147483647
302static const char hexdigit[] =
"0123456789abcdef0123456789ABCDEF";
305#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + defined(IBM) != 1
306Exactly one of IEEE_LITTLE_ENDIAN, IEEE_BIG_ENDIAN, VAX, or IBM should be defined.
309typedef union {
double d; ULong L[2]; }
U;
314# ifdef IEEE_LITTLE_ENDIAN
315# define word0(x) (((ULong *)&(x))[1])
316# define word1(x) (((ULong *)&(x))[0])
318# define word0(x) (((ULong *)&(x))[0])
319# define word1(x) (((ULong *)&(x))[1])
323# ifdef IEEE_LITTLE_ENDIAN
324# define word0(x) ((x).L[1])
325# define word1(x) ((x).L[0])
327# define word0(x) ((x).L[0])
328# define word1(x) ((x).L[1])
330# define dval(x) ((x).d)
337#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm__)
338#define Storeinc(a,b,c) (((unsigned short *)(a))[1] = (unsigned short)(b), \
339((unsigned short *)(a))[0] = (unsigned short)(c), (a)++)
341#define Storeinc(a,b,c) (((unsigned short *)(a))[0] = (unsigned short)(b), \
342((unsigned short *)(a))[1] = (unsigned short)(c), (a)++)
354#define Exp_msk1 0x100000
355#define Exp_msk11 0x100000
356#define Exp_mask 0x7ff00000
360#define Exp_1 0x3ff00000
361#define Exp_11 0x3ff00000
363#define Frac_mask 0xfffff
364#define Frac_mask1 0xfffff
367#define Bndry_mask 0xfffff
368#define Bndry_mask1 0xfffff
370#define Sign_bit 0x80000000
377#define Avoid_Underflow
379#undef Sudden_Underflow
385#define Flt_Rounds FLT_ROUNDS
391#ifdef Honor_FLT_ROUNDS
392#define Rounding rounding
393#undef Check_FLT_ROUNDS
394#define Check_FLT_ROUNDS
396#define Rounding Flt_Rounds
400#undef Check_FLT_ROUNDS
401#undef Honor_FLT_ROUNDS
403#undef Sudden_Underflow
404#define Sudden_Underflow
410#define Exp_msk1 0x1000000
411#define Exp_msk11 0x1000000
412#define Exp_mask 0x7f000000
415#define Exp_1 0x41000000
416#define Exp_11 0x41000000
418#define Frac_mask 0xffffff
419#define Frac_mask1 0xffffff
422#define Bndry_mask 0xefffff
423#define Bndry_mask1 0xffffff
425#define Sign_bit 0x80000000
427#define Tiny0 0x100000
437#define Exp_msk11 0x800000
438#define Exp_mask 0x7f80
441#define Exp_1 0x40800000
444#define Frac_mask 0x7fffff
445#define Frac_mask1 0xffff007f
448#define Bndry_mask 0xffff007f
449#define Bndry_mask1 0xffff007f
451#define Sign_bit 0x8000
465#define rounded_product(a,b) ((a) = rnd_prod((a), (b)))
466#define rounded_quotient(a,b) ((a) = rnd_quot((a), (b)))
467extern double rnd_prod(
double,
double), rnd_quot(
double,
double);
469#define rounded_product(a,b) ((a) *= (b))
470#define rounded_quotient(a,b) ((a) /= (b))
473#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
474#define Big1 0xffffffff
480#define FFFFFFFF 0xffffffffUL
494#define Llong long long
497#define ULLong unsigned Llong
501#define MULTIPLE_THREADS 1
503#ifndef MULTIPLE_THREADS
504#define ACQUIRE_DTOA_LOCK(n)
505#define FREE_DTOA_LOCK(n)
507#define ACQUIRE_DTOA_LOCK(n)
508#define FREE_DTOA_LOCK(n)
511#ifndef ATOMIC_PTR_CAS
512#define ATOMIC_PTR_CAS(var, old, new) ((var) = (new), (void *)(old))
514#ifndef RUBY_ATOMIC_PTR_LOAD
515#define RUBY_ATOMIC_PTR_LOAD(var) (var)
521#define UNLIKELY(x) (x)
524#define ASSUME(x) (void)(x)
531 int k, maxwds, sign, wds;
544 rv = (
Bigint *)MALLOC(
sizeof(
Bigint) + (x-1)*
sizeof(ULong));
545 if (!rv)
return NULL;
548 rv->sign = rv->wds = 0;
559#define Bfree(v) Bclear(&(v))
561#define Bcopy(x,y) memcpy((char *)&(x)->sign, (char *)&(y)->sign, \
562(y)->wds*sizeof(Long) + 2*sizeof(int))
565multadd(
Bigint *b,
int m,
int a)
585 y = *x * (ULLong)m + carry;
587 *x++ = (ULong)(y & FFFFFFFF);
591 y = (xi & 0xffff) * m + carry;
592 z = (xi >> 16) * m + (y >> 16);
594 *x++ = (z << 16) + (y & 0xffff);
603 if (wds >= b->maxwds) {
613 b->x[wds++] = (ULong)carry;
620s2b(
const char *s,
int nd0,
int nd, ULong y9)
627 for (k = 0, y = 1; x > y; y <<= 1, k++) ;
636 b->x[0] = y9 & 0xffff;
637 b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
644 b = multadd(b, 10, *s++ -
'0');
651 for (; i < nd; i++) {
652 b = multadd(b, 10, *s++ -
'0');
659hi0bits(
register ULong x)
663 if (!(x & 0xffff0000)) {
667 if (!(x & 0xff000000)) {
671 if (!(x & 0xf0000000)) {
675 if (!(x & 0xc0000000)) {
679 if (!(x & 0x80000000)) {
681 if (!(x & 0x40000000))
691 register ULong x = *y;
742#define Bzero_p(b) (!(b)->x[0] && (b)->wds <= 1)
749 ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
760 if (Bzero_p(a) || Bzero_p(b)) {
768 if (a->wds < b->wds) {
781 for (x = c->x, xa = x + wc; x < xa; x++)
789 for (; xb < xbe; xc0++) {
790 if ((y = *xb++) != 0) {
795 z = *x++ * (ULLong)y + *xc + carry;
797 *xc++ = (ULong)(z & FFFFFFFF);
804 for (; xb < xbe; xb++, xc0++) {
805 if ((y = *xb & 0xffff) != 0) {
810 z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
812 z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
818 if ((y = *xb >> 16) != 0) {
824 z = (*x & 0xffff) * y + (*xc >> 16) + carry;
827 z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
834 for (; xb < xbe; xc0++) {
840 z = *x++ * y + *xc + carry;
849 for (xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
861 static const int p05[3] = { 5, 25, 125 };
863 if ((i = k & 3) != 0) {
864 b = multadd(b, p05[i-1], 0);
868#define b_cache(var, addr, new_expr) \
869 if ((var = RUBY_ATOMIC_PTR_LOAD(addr)) != 0) {} else { \
871 ACQUIRE_DTOA_LOCK(1); \
872 if (!(var = RUBY_ATOMIC_PTR_LOAD(addr)) && (var = (new_expr)) != 0) { \
874 tmp = ATOMIC_PTR_CAS(addr, NULL, var); \
877 if (UNLIKELY(tmp)) { \
890 b_cache(p5, p5s, i2b(625));
900 b_cache(p51, p5->next, mult(p5, p5));
911 ULong *x, *x1, *xe, z;
913 if (!k || Bzero_p(b))
return b;
922 for (i = b->maxwds; n1 > i; i <<= 1)
930 for (i = 0; i < n; i++)
950 *x1++ = *x << k & 0xffff | z;
969 ULong *xa, *xa0, *xb, *xb0;
975 if (i > 1 && !a->x[i-1])
976 Bug(
"cmp called with a->x[a->wds-1] == 0");
977 if (j > 1 && !b->x[j-1])
978 Bug(
"cmp called with b->x[b->wds-1] == 0");
988 return *xa < *xb ? -1 : 1;
1001 ULong *xa, *xae, *xb, *xbe, *xc;
1014 if (!c)
return NULL;
1028 if (!c)
return NULL;
1040 y = (ULLong)*xa++ - *xb++ - borrow;
1041 borrow = y >> 32 & (ULong)1;
1042 *xc++ = (ULong)(y & FFFFFFFF);
1046 borrow = y >> 32 & (ULong)1;
1047 *xc++ = (ULong)(y & FFFFFFFF);
1052 y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
1053 borrow = (y & 0x10000) >> 16;
1054 z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
1055 borrow = (z & 0x10000) >> 16;
1059 y = (*xa & 0xffff) - borrow;
1060 borrow = (y & 0x10000) >> 16;
1061 z = (*xa++ >> 16) - borrow;
1062 borrow = (z & 0x10000) >> 16;
1067 y = *xa++ - *xb++ - borrow;
1068 borrow = (y & 0x10000) >> 16;
1073 borrow = (y & 0x10000) >> 16;
1091 L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
1092#ifndef Avoid_Underflow
1093#ifndef Sudden_Underflow
1102#ifndef Avoid_Underflow
1103#ifndef Sudden_Underflow
1106 L = -L >> Exp_shift;
1107 if (L < Exp_shift) {
1108 word0(a) = 0x80000 >> L;
1114 word1(a) = L >= 31 ? 1 : 1 << 31 - L;
1125 ULong *xa, *xa0, w, y, z;
1139 if (!y) Bug(
"zero y in b2d");
1145 d0 = Exp_1 | y >> (Ebits - k);
1146 w = xa > xa0 ? *--xa : 0;
1147 d1 = y << ((32-Ebits) + k) | w >> (Ebits - k);
1150 z = xa > xa0 ? *--xa : 0;
1152 d0 = Exp_1 | y << k | z >> (32 - k);
1153 y = xa > xa0 ? *--xa : 0;
1154 d1 = z << k | y >> (32 - k);
1161 if (k < Ebits + 16) {
1162 z = xa > xa0 ? *--xa : 0;
1163 d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
1164 w = xa > xa0 ? *--xa : 0;
1165 y = xa > xa0 ? *--xa : 0;
1166 d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
1169 z = xa > xa0 ? *--xa : 0;
1170 w = xa > xa0 ? *--xa : 0;
1172 d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
1173 y = xa > xa0 ? *--xa : 0;
1174 d1 = w << k + 16 | y << k;
1178 word0(d) = d0 >> 16 | d0 << 16;
1179 word1(d) = d1 >> 16 | d1 << 16;
1188d2b(
double d_,
int *e,
int *bits)
1194#ifndef Sudden_Underflow
1202 d0 = word0(d) >> 16 | word0(d) << 16;
1203 d1 = word1(d) >> 16 | word1(d) << 16;
1214 if (!b)
return NULL;
1219#ifdef Sudden_Underflow
1220 de = (int)(d0 >> Exp_shift);
1225 if ((de = (
int)(d0 >> Exp_shift)) != 0)
1229 if ((y = d1) != 0) {
1230 if ((k = lo0bits(&y)) != 0) {
1231 x[0] = y | z << (32 - k);
1236#ifndef Sudden_Underflow
1239 b->wds = (x[1] = z) ? 2 : 1;
1244 Bug(
"Zero passed to d2b");
1248#ifndef Sudden_Underflow
1256 if (k = lo0bits(&y))
1258 x[0] = y | z << 32 - k & 0xffff;
1259 x[1] = z >> k - 16 & 0xffff;
1265 x[1] = y >> 16 | z << 16 - k & 0xffff;
1266 x[2] = z >> k & 0xffff;
1281 Bug(
"Zero passed to d2b");
1299#ifndef Sudden_Underflow
1303 *e = (de - Bias - (P-1) << 2) + k;
1304 *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
1306 *e = de - Bias - (P-1) + k;
1309#ifndef Sudden_Underflow
1312 *e = de - Bias - (P-1) + 1 + k;
1314 *bits = 32*i - hi0bits(x[i-1]);
1316 *bits = (i+2)*16 - hi0bits(x[i]);
1331 dval(da) = b2d(a, &ka);
1332 dval(db) = b2d(b, &kb);
1334 k = ka - kb + 32*(a->wds - b->wds);
1336 k = ka - kb + 16*(a->wds - b->wds);
1340 word0(da) += (k >> 2)*Exp_msk1;
1346 word0(db) += (k >> 2)*Exp_msk1;
1352 word0(da) += k*Exp_msk1;
1355 word0(db) += k*Exp_msk1;
1358 return dval(da) / dval(db);
1363 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1364 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
1373bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
1374static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
1375#ifdef Avoid_Underflow
1376 9007199254740992.*9007199254740992.e-256
1384#define Scale_Bit 0x10
1388bigtens[] = { 1e16, 1e32, 1e64 };
1389static const double tinytens[] = { 1e-16, 1e-32, 1e-64 };
1392bigtens[] = { 1e16, 1e32 };
1393static const double tinytens[] = { 1e-16, 1e-32 };
1405#define NAN_WORD0 0x7ff80000
1413match(
const char **sp,
char *t)
1416 const char *s = *sp;
1419 if ((c = *++s) >=
'A' && c <=
'Z')
1430hexnan(
double *rvp,
const char **sp)
1434 int havedig, udx0, xshift;
1437 havedig = xshift = 0;
1440 while (c = *(
const unsigned char*)++s) {
1441 if (c >=
'0' && c <=
'9')
1443 else if (c >=
'a' && c <=
'f')
1445 else if (c >=
'A' && c <=
'F')
1447 else if (c <=
' ') {
1448 if (udx0 && havedig) {
1454 else if ( c ==
')' && havedig) {
1467 x[0] = (x[0] << 4) | (x[1] >> 28);
1468 x[1] = (x[1] << 4) | c;
1470 if ((x[0] &= 0xfffff) || x[1]) {
1471 word0(*rvp) = Exp_mask | x[0];
1478NO_SANITIZE(
"unsigned-integer-overflow",
double strtod(
const char *s00,
char **se));
1480strtod(
const char *s00,
char **se)
1482#ifdef Avoid_Underflow
1485 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
1486 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
1487 const char *s, *s0, *s1;
1492 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
1494 int inexact, oldinexact;
1496#ifdef Honor_FLT_ROUNDS
1504 sign = nz0 = nz = 0;
1529 if (s[1] ==
'x' || s[1] ==
'X') {
1535 if (!*++s || (!(s1 = strchr(hexdigit, *s)) && *s !=
'.'))
goto ret0;
1537 while (*++s ==
'0');
1539 s1 = strchr(hexdigit, *s);
1543 adj += aadj * ((s1 - hexdigit) & 15);
1546 }
while (*++s && (s1 = strchr(hexdigit, *s)));
1549 if ((*s ==
'.') && *++s && (s1 = strchr(hexdigit, *s))) {
1556 for (; *s && (s1 = strchr(hexdigit, *s)); ++s) {
1557 adj += aadj * ((s1 - hexdigit) & 15);
1558 if ((aadj /= 16) == 0.0) {
1559 while (*++s && strchr(hexdigit, *s));
1565 if (*s ==
'P' || *s ==
'p') {
1566 dsign = 0x2C - *++s;
1567 if (abs(dsign) == 1) s++;
1572 if (c <
'0' ||
'9' < c)
goto ret0;
1579 if (nd + dsign * nd0 > 2095) {
1580 while (
'0' <= c && c <=
'9') c = *++s;
1583 }
while (
'0' <= c && c <=
'9');
1586 dval(rv) = ldexp(adj, nd0);
1590 while (*++s ==
'0') ;
1596 for (nd = nf = 0; (c = *s) >=
'0' && c <=
'9'; nd++, s++)
1599 else if (nd < DBL_DIG + 2)
1603 s1 = localeconv()->decimal_point;
1626 for (; c ==
'0'; c = *++s)
1628 if (c >
'0' && c <=
'9') {
1636 for (; c >=
'0' && c <=
'9'; c = *++s) {
1639 if (nd > DBL_DIG * 4) {
1644 for (i = 1; i < nz; i++)
1647 else if (nd <= DBL_DIG + 2)
1651 else if (nd <= DBL_DIG + 2)
1659 if (c ==
'e' || c ==
'E') {
1660 if (!nd && !nz && !nz0) {
1671 if (c >=
'0' && c <=
'9') {
1674 if (c >
'0' && c <=
'9') {
1677 while ((c = *++s) >=
'0' && c <=
'9')
1679 if (s - s1 > 8 || L > 19999)
1702 if (match(&s,
"nf")) {
1704 if (!match(&s,
"inity"))
1706 word0(rv) = 0x7ff00000;
1713 if (match(&s,
"an")) {
1714 word0(rv) = NAN_WORD0;
1715 word1(rv) = NAN_WORD1;
1739 k = nd < DBL_DIG + 2 ? nd : DBL_DIG + 2;
1744 oldinexact = get_inexact();
1746 dval(rv) = tens[k - 9] * dval(rv) + z;
1748 bd0 = bb = bd = bs = delta = 0;
1751#ifndef Honor_FLT_ROUNDS
1759 if (e <= Ten_pmax) {
1761 goto vax_ovfl_check;
1763#ifdef Honor_FLT_ROUNDS
1766 dval(rv) = -dval(rv);
1770 rounded_product(dval(rv), tens[e]);
1775 if (e <= Ten_pmax + i) {
1779#ifdef Honor_FLT_ROUNDS
1782 dval(rv) = -dval(rv);
1787 dval(rv) *= tens[i];
1793 word0(rv) -= P*Exp_msk1;
1794 rounded_product(dval(rv), tens[e]);
1795 if ((word0(rv) & Exp_mask)
1796 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
1798 word0(rv) += P*Exp_msk1;
1800 rounded_product(dval(rv), tens[e]);
1805#ifndef Inaccurate_Divide
1806 else if (e >= -Ten_pmax) {
1807#ifdef Honor_FLT_ROUNDS
1810 dval(rv) = -dval(rv);
1814 rounded_quotient(dval(rv), tens[-e]);
1825 oldinexact = get_inexact();
1827#ifdef Avoid_Underflow
1830#ifdef Honor_FLT_ROUNDS
1831 if ((rounding = Flt_Rounds) >= 2) {
1833 rounding = rounding == 2 ? 0 : 2;
1844 if ((i = e1 & 15) != 0)
1845 dval(rv) *= tens[i];
1847 if (e1 > DBL_MAX_10_EXP) {
1854#ifdef Honor_FLT_ROUNDS
1862 word0(rv) = Exp_mask;
1866 word0(rv) = Exp_mask;
1872 dval(rv0) *= dval(rv0);
1883 for (j = 0; e1 > 1; j++, e1 >>= 1)
1885 dval(rv) *= bigtens[j];
1887 word0(rv) -= P*Exp_msk1;
1888 dval(rv) *= bigtens[j];
1889 if ((z = word0(rv) & Exp_mask)
1890 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
1892 if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
1899 word0(rv) += P*Exp_msk1;
1904 if ((i = e1 & 15) != 0)
1905 dval(rv) /= tens[i];
1907 if (e1 >= 1 << n_bigtens)
1909#ifdef Avoid_Underflow
1912 for (j = 0; e1 > 0; j++, e1 >>= 1)
1914 dval(rv) *= tinytens[j];
1915 if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask)
1916 >> Exp_shift)) > 0) {
1921 word0(rv) = (P+2)*Exp_msk1;
1923 word0(rv) &= 0xffffffff << (j-32);
1926 word1(rv) &= 0xffffffff << j;
1929 for (j = 0; e1 > 1; j++, e1 >>= 1)
1931 dval(rv) *= tinytens[j];
1933 dval(rv0) = dval(rv);
1934 dval(rv) *= tinytens[j];
1936 dval(rv) = 2.*dval(rv0);
1937 dval(rv) *= tinytens[j];
1949#ifndef Avoid_Underflow
1964 bd0 = s2b(s0, nd0, nd, y);
1968 bd = Balloc(bd0->k);
1969 if (!bd)
goto retfree;
1971 bb = d2b(dval(rv), &bbe, &bbbits);
1972 if (!bb)
goto retfree;
1974 if (!bs)
goto retfree;
1989#ifdef Honor_FLT_ROUNDS
1993#ifdef Avoid_Underflow
2001#ifdef Sudden_Underflow
2003 j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
2018#ifdef Avoid_Underflow
2021 i = bb2 < bd2 ? bb2 : bd2;
2030 bs = pow5mult(bs, bb5);
2031 if (!bs)
goto retfree;
2035 if (!bb)
goto retfree;
2038 bb = lshift(bb, bb2);
2039 if (!bb)
goto retfree;
2042 bd = pow5mult(bd, bd5);
2043 if (!bd)
goto retfree;
2046 bd = lshift(bd, bd2);
2047 if (!bd)
goto retfree;
2050 bs = lshift(bs, bs2);
2051 if (!bs)
goto retfree;
2053 delta = diff(bb, bd);
2054 if (!delta)
goto retfree;
2055 dsign = delta->sign;
2058#ifdef Honor_FLT_ROUNDS
2059 if (rounding != 1) {
2062 if (!delta->x[0] && delta->wds <= 1) {
2078 && !(word0(rv) & Frac_mask)) {
2079 y = word0(rv) & Exp_mask;
2080#ifdef Avoid_Underflow
2081 if (!scale || y > 2*P*Exp_msk1)
2086 delta = lshift(delta,Log2P);
2087 if (!delta)
goto nomem;
2088 if (cmp(delta, bs) <= 0)
2093#ifdef Avoid_Underflow
2094 if (scale && (y = word0(rv) & Exp_mask)
2096 word0(adj) += (2*P+1)*Exp_msk1 - y;
2098#ifdef Sudden_Underflow
2099 if ((word0(rv) & Exp_mask) <=
2101 word0(rv) += P*Exp_msk1;
2102 dval(rv) += adj*ulp(dval(rv));
2103 word0(rv) -= P*Exp_msk1;
2108 dval(rv) += adj*ulp(dval(rv));
2112 adj = ratio(delta, bs);
2115 if (adj <= 0x7ffffffe) {
2119 if (!((rounding>>1) ^ dsign))
2124#ifdef Avoid_Underflow
2125 if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
2126 word0(adj) += (2*P+1)*Exp_msk1 - y;
2128#ifdef Sudden_Underflow
2129 if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
2130 word0(rv) += P*Exp_msk1;
2131 adj *= ulp(dval(rv));
2136 word0(rv) -= P*Exp_msk1;
2141 adj *= ulp(dval(rv));
2154 if (dsign || word1(rv) || word0(rv) & Bndry_mask
2156#ifdef Avoid_Underflow
2157 || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1
2159 || (word0(rv) & Exp_mask) <= Exp_msk1
2164 if (!delta->x[0] && delta->wds <= 1)
2169 if (!delta->x[0] && delta->wds <= 1) {
2176 delta = lshift(delta,Log2P);
2177 if (!delta)
goto retfree;
2178 if (cmp(delta, bs) > 0)
2185 if ((word0(rv) & Bndry_mask1) == Bndry_mask1
2187#ifdef Avoid_Underflow
2188 (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
2189 ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :
2193 word0(rv) = (word0(rv) & Exp_mask)
2200#ifdef Avoid_Underflow
2206 else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
2209#ifdef Sudden_Underflow
2210 L = word0(rv) & Exp_mask;
2214#ifdef Avoid_Underflow
2215 if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1))
2223#ifdef Avoid_Underflow
2225 L = word0(rv) & Exp_mask;
2226 if (L <= (2*P+1)*Exp_msk1) {
2227 if (L > (P+2)*Exp_msk1)
2236 L = (word0(rv) & Exp_mask) - Exp_msk1;
2238 word0(rv) = L | Bndry_mask1;
2239 word1(rv) = 0xffffffff;
2247 if (!(word1(rv) & LSB))
2251 dval(rv) += ulp(dval(rv));
2254 dval(rv) -= ulp(dval(rv));
2255#ifndef Sudden_Underflow
2260#ifdef Avoid_Underflow
2266 if ((aadj = ratio(delta, bs)) <= 2.) {
2268 aadj = dval(aadj1) = 1.;
2269 else if (word1(rv) || word0(rv) & Bndry_mask) {
2270#ifndef Sudden_Underflow
2271 if (word1(rv) == Tiny1 && !word0(rv))
2281 if (aadj < 2./FLT_RADIX)
2282 aadj = 1./FLT_RADIX;
2285 dval(aadj1) = -aadj;
2290 dval(aadj1) = dsign ? aadj : -aadj;
2291#ifdef Check_FLT_ROUNDS
2301 if (Flt_Rounds == 0)
2305 y = word0(rv) & Exp_mask;
2309 if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
2310 dval(rv0) = dval(rv);
2311 word0(rv) -= P*Exp_msk1;
2312 adj = dval(aadj1) * ulp(dval(rv));
2314 if ((word0(rv) & Exp_mask) >=
2315 Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
2316 if (word0(rv0) == Big0 && word1(rv0) == Big1)
2323 word0(rv) += P*Exp_msk1;
2326#ifdef Avoid_Underflow
2327 if (scale && y <= 2*P*Exp_msk1) {
2328 if (aadj <= 0x7fffffff) {
2329 if ((z = (
int)aadj) <= 0)
2332 dval(aadj1) = dsign ? aadj : -aadj;
2334 word0(aadj1) += (2*P+1)*Exp_msk1 - y;
2336 adj = dval(aadj1) * ulp(dval(rv));
2339#ifdef Sudden_Underflow
2340 if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
2341 dval(rv0) = dval(rv);
2342 word0(rv) += P*Exp_msk1;
2343 adj = dval(aadj1) * ulp(dval(rv));
2346 if ((word0(rv) & Exp_mask) < P*Exp_msk1)
2348 if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
2351 if (word0(rv0) == Tiny0 && word1(rv0) == Tiny1)
2358 word0(rv) -= P*Exp_msk1;
2361 adj = dval(aadj1) * ulp(dval(rv));
2372 if (y <= (P-1)*Exp_msk1 && aadj > 1.) {
2373 dval(aadj1) = (double)(
int)(aadj + 0.5);
2375 dval(aadj1) = -dval(aadj1);
2377 adj = dval(aadj1) * ulp(dval(rv));
2382 z = word0(rv) & Exp_mask;
2384#ifdef Avoid_Underflow
2392 if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
2393 if (aadj < .4999999 || aadj > .5000001)
2396 else if (aadj < .4999999/FLT_RADIX)
2409 word0(rv0) = Exp_1 + (70 << Exp_shift);
2414 else if (!oldinexact)
2417#ifdef Avoid_Underflow
2419 word0(rv0) = Exp_1 - 2*P*Exp_msk1;
2421 dval(rv) *= dval(rv0);
2424 if (word0(rv) == 0 && word1(rv) == 0)
2430 if (inexact && !(word0(rv) & Exp_mask)) {
2433 dval(rv0) *= dval(rv0);
2445 return sign ? -dval(rv) : dval(rv);
2448NO_SANITIZE(
"unsigned-integer-overflow",
static int quorem(
Bigint *b,
Bigint *S));
2453 ULong *bx, *bxe, q, *sx, *sxe;
2455 ULLong borrow, carry, y, ys;
2457 ULong borrow, carry, y, ys;
2466 Bug(
"oversize b in quorem");
2474 q = *bxe / (*sxe + 1);
2477 Bug(
"oversized quotient in quorem");
2484 ys = *sx++ * (ULLong)q + carry;
2486 y = *bx - (ys & FFFFFFFF) - borrow;
2487 borrow = y >> 32 & (ULong)1;
2488 *bx++ = (ULong)(y & FFFFFFFF);
2492 ys = (si & 0xffff) * q + carry;
2493 zs = (si >> 16) * q + (ys >> 16);
2495 y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
2496 borrow = (y & 0x10000) >> 16;
2497 z = (*bx >> 16) - (zs & 0xffff) - borrow;
2498 borrow = (z & 0x10000) >> 16;
2501 ys = *sx++ * q + carry;
2503 y = *bx - (ys & 0xffff) - borrow;
2504 borrow = (y & 0x10000) >> 16;
2508 }
while (sx <= sxe);
2511 while (--bxe > bx && !*bxe)
2516 if (cmp(b, S) >= 0) {
2526 y = *bx - (ys & FFFFFFFF) - borrow;
2527 borrow = y >> 32 & (ULong)1;
2528 *bx++ = (ULong)(y & FFFFFFFF);
2532 ys = (si & 0xffff) + carry;
2533 zs = (si >> 16) + (ys >> 16);
2535 y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
2536 borrow = (y & 0x10000) >> 16;
2537 z = (*bx >> 16) - (zs & 0xffff) - borrow;
2538 borrow = (z & 0x10000) >> 16;
2543 y = *bx - (ys & 0xffff) - borrow;
2544 borrow = (y & 0x10000) >> 16;
2548 }
while (sx <= sxe);
2552 while (--bxe > bx && !*bxe)
2560#ifndef MULTIPLE_THREADS
2561static char *dtoa_result;
2564#ifndef MULTIPLE_THREADS
2568 return dtoa_result = MALLOC(i);
2571#define rv_alloc(i) MALLOC(i)
2575nrv_alloc(
const char *s,
char **rve,
size_t n)
2579 t = rv = rv_alloc(n);
2580 if (!rv)
return NULL;
2581 while ((*t = *s++) != 0) t++;
2587#define rv_strdup(s, rve) nrv_alloc((s), (rve), strlen(s)+1)
2589#ifndef MULTIPLE_THREADS
2603static const char INFSTR[] =
"Infinity";
2604static const char NANSTR[] =
"NaN";
2605static const char ZEROSTR[] =
"0";
2642dtoa(
double d_,
int mode,
int ndigits,
int *decpt,
int *sign,
char **rve)
2678 int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
2679 j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
2680 spec_case, try_quick, half = 0;
2682#ifndef Sudden_Underflow
2686 Bigint *b, *b1, *delta, *mlo = 0, *mhi = 0, *S;
2690#ifdef Honor_FLT_ROUNDS
2694 int inexact, oldinexact;
2699#ifndef MULTIPLE_THREADS
2701 freedtoa(dtoa_result);
2706 if (word0(d) & Sign_bit) {
2709 word0(d) &= ~Sign_bit;
2714#if defined(IEEE_Arith) + defined(VAX)
2716 if ((word0(d) & Exp_mask) == Exp_mask)
2718 if (word0(d) == 0x8000)
2724 if (!word1(d) && !(word0(d) & 0xfffff))
2725 return rv_strdup(INFSTR, rve);
2727 return rv_strdup(NANSTR, rve);
2735 return rv_strdup(ZEROSTR, rve);
2739 try_quick = oldinexact = get_inexact();
2742#ifdef Honor_FLT_ROUNDS
2743 if ((rounding = Flt_Rounds) >= 2) {
2745 rounding = rounding == 2 ? 0 : 2;
2752 b = d2b(dval(d), &be, &bbits);
2753 if (!b)
return NULL;
2754#ifdef Sudden_Underflow
2755 i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
2757 if ((i = (
int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) {
2760 word0(d2) &= Frac_mask1;
2761 word0(d2) |= Exp_11;
2763 if (j = 11 - hi0bits(word0(d2) & Frac_mask))
2794#ifndef Sudden_Underflow
2800 i = bbits + be + (Bias + (P-1) - 1);
2801 x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32)
2802 : word1(d) << (32 - i);
2804 word0(d2) -= 31*Exp_msk1;
2805 i -= (Bias + (P-1) - 1) + 1;
2809 ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
2811 if (ds < 0. && ds != k)
2814 if (k >= 0 && k <= Ten_pmax) {
2815 if (dval(d) < tens[k])
2838 if (mode < 0 || mode > 9)
2842#ifdef Check_FLT_ROUNDS
2843 try_quick = Rounding == 1;
2867 ilim = ilim1 = i = ndigits;
2873 if (ckd_add(&i, ndigits, k + 1)) {
2882 s = s0 = rv_alloc(i+1);
2888#ifdef Honor_FLT_ROUNDS
2889 if (mode > 1 && rounding != 1)
2893 if (ilim >= 0 && ilim <= Quick_max && try_quick) {
2908 dval(d) /= bigtens[n_bigtens-1];
2911 for (; j; j >>= 1, i++)
2918 else if ((j1 = -k) != 0) {
2919 dval(d) *= tens[j1 & 0xf];
2920 for (j = j1 >> 4; j; j >>= 1, i++)
2923 dval(d) *= bigtens[i];
2926 if (k_check && dval(d) < 1. && ilim > 0) {
2934 dval(eps) = ieps*dval(d) + 7.;
2935 word0(eps) -= (P-1)*Exp_msk1;
2939 if (dval(d) > dval(eps))
2941 if (dval(d) < -dval(eps))
2950 dval(eps) = 0.5/tens[ilim-1] - dval(eps);
2954 *s++ =
'0' + (int)L;
2955 if (dval(d) < dval(eps))
2957 if (1. - dval(d) < dval(eps))
2968 dval(eps) *= tens[ilim-1];
2969 for (i = 1;; i++, dval(d) *= 10.) {
2970 L = (Long)(dval(d));
2971 if (!(dval(d) -= L))
2973 *s++ =
'0' + (int)L;
2975 if (dval(d) > 0.5 + dval(eps))
2977 else if (dval(d) < 0.5 - dval(eps)) {
2978 while (*--s ==
'0') ;
2983 if ((*(s-1) -
'0') & 1) {
3001 if (be >= 0 && k <= Int_max) {
3004 if (ndigits < 0 && ilim <= 0) {
3006 if (ilim < 0 || dval(d) <= 5*ds)
3010 for (i = 1;; i++, dval(d) *= 10.) {
3011 L = (Long)(dval(d) / ds);
3013#ifdef Check_FLT_ROUNDS
3020 *s++ =
'0' + (int)L;
3028#ifdef Honor_FLT_ROUNDS
3032 case 2:
goto bump_up;
3036 if (dval(d) > ds || (dval(d) == ds && (L & 1))) {
3056#ifndef Sudden_Underflow
3057 denorm ? be + (Bias + (P-1) - 1 + 1) :
3060 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
3067 if (!mhi)
goto nomem;
3069 if (m2 > 0 && s2 > 0) {
3070 i = m2 < s2 ? m2 : s2;
3078 mhi = pow5mult(mhi, m5);
3079 if (!mhi)
goto nomem;
3085 if ((j = b5 - m5) != 0) {
3091 b = pow5mult(b, b5);
3098 S = pow5mult(S, s5);
3105 if ((mode < 2 || leftright)
3106#ifdef Honor_FLT_ROUNDS
3110 if (!word1(d) && !(word0(d) & Bndry_mask)
3111#ifndef Sudden_Underflow
3112 && word0(d) & (Exp_mask & ~Exp_msk1)
3130 if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0)
3133 if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) != 0)
3159 b = multadd(b, 10, 0);
3162 mhi = multadd(mhi, 10, 0);
3163 if (!mhi)
goto nomem;
3168 if (ilim <= 0 && (mode == 3 || mode == 5)) {
3169 if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
3182 mhi = lshift(mhi, m2);
3183 if (!mhi)
goto nomem;
3192 mhi = Balloc(mhi->k);
3193 if (!mhi)
goto nomem;
3195 mhi = lshift(mhi, Log2P);
3196 if (!mhi)
goto nomem;
3200 dig = quorem(b,S) +
'0';
3205 delta = diff(S, mhi);
3206 if (!delta)
goto nomem;
3207 j1 = delta->sign ? 1 : cmp(b, delta);
3210 if (j1 == 0 && mode != 1 && !(word1(d) & 1)
3211#ifdef Honor_FLT_ROUNDS
3220 else if (!b->x[0] && b->wds <= 1)
3227 if (j < 0 || (j == 0 && mode != 1
3232 if (!b->x[0] && b->wds <= 1) {
3238#ifdef Honor_FLT_ROUNDS
3241 case 0:
goto accept_dig;
3242 case 2:
goto keep_dig;
3249 if ((j1 > 0 || (j1 == 0 && (dig & 1))) && dig++ ==
'9')
3257#ifdef Honor_FLT_ROUNDS
3269#ifdef Honor_FLT_ROUNDS
3275 b = multadd(b, 10, 0);
3278 mlo = mhi = multadd(mhi, 10, 0);
3279 if (!mlo)
goto nomem;
3282 mlo = multadd(mlo, 10, 0);
3283 if (!mlo)
goto nomem;
3284 mhi = multadd(mhi, 10, 0);
3285 if (!mhi)
goto nomem;
3291 *s++ = dig = quorem(b,S) +
'0';
3292 if (!b->x[0] && b->wds <= 1) {
3300 b = multadd(b, 10, 0);
3306#ifdef Honor_FLT_ROUNDS
3308 case 0:
goto trimzeros;
3309 case 2:
goto roundoff;
3315 if (j > 0 || (j == 0 && (dig & 1))) {
3323 if (!half || (*s -
'0') & 1)
3327 while (*--s ==
'0') ;
3333 if (mlo && mlo != mhi)
3341 word0(d) = Exp_1 + (70 << Exp_shift);
3346 else if (!oldinexact)
3358 if (mlo && mlo != mhi)
3393#define DBL_MANH_SIZE 20
3394#define DBL_MANL_SIZE 32
3395#define DBL_ADJ (DBL_MAX_EXP - 2)
3396#define SIGFIGS ((DBL_MANT_DIG + 3) / 4 + 1)
3397#define dexp_get(u) ((int)(word0(u) >> Exp_shift) & ~Exp_msk1)
3398#define dexp_set(u,v) (word0(u) = (((int)(word0(u)) & ~Exp_mask) | ((v) << Exp_shift)))
3399#define dmanh_get(u) ((uint32_t)(word0(u) & Frac_mask))
3400#define dmanl_get(u) ((uint32_t)word1(u))
3428hdtoa(
double d,
const char *xdigs,
int ndigits,
int *decpt,
int *sign,
char **rve)
3433 uint32_t manh, manl;
3436 if (word0(u) & Sign_bit) {
3439 word0(u) &= ~Sign_bit;
3446 return rv_strdup(INFSTR, rve);
3448 else if (isnan(d)) {
3450 return rv_strdup(NANSTR, rve);
3452 else if (d == 0.0) {
3454 return rv_strdup(ZEROSTR, rve);
3456 else if (dexp_get(u)) {
3457 *decpt = dexp_get(u) - DBL_ADJ;
3460 u.d *= 5.363123171977039e+154 ;
3461 *decpt = dexp_get(u) - (514 + DBL_ADJ);
3471 bufsize = (ndigits > 0) ? ndigits : SIGFIGS;
3472 s0 = rv_alloc(bufsize+1);
3473 if (!s0)
return NULL;
3476 if (SIGFIGS > ndigits && ndigits > 0) {
3478 int offset = 4 * ndigits + DBL_MAX_EXP - 4 - DBL_MANT_DIG;
3479 dexp_set(u, offset);
3482 *decpt += dexp_get(u) - offset;
3485 manh = dmanh_get(u);
3486 manl = dmanl_get(u);
3488 for (s = s0 + 1; s < s0 + bufsize; s++) {
3489 *s = xdigs[(manh >> (DBL_MANH_SIZE - 4)) & 0xf];
3490 manh = (manh << 4) | (manl >> (DBL_MANL_SIZE - 4));
3496 for (ndigits = SIGFIGS; s0[ndigits - 1] ==
'0'; ndigits--)
#define ISDIGIT
Old name of rb_isdigit.
#define strtod(s, e)
Just another name of ruby_strtod.
#define errno
Ractor-aware version of errno.