diff options
Diffstat (limited to 'Python/dtoa.c')
-rw-r--r-- | Python/dtoa.c | 184 |
1 files changed, 129 insertions, 55 deletions
diff --git a/Python/dtoa.c b/Python/dtoa.c index b7bb7ac..25eb9a7 100644 --- a/Python/dtoa.c +++ b/Python/dtoa.c @@ -151,9 +151,18 @@ #endif -typedef uint32_t ULong; -typedef int32_t Long; -typedef uint64_t ULLong; +#if defined(HAVE_UINT32_T) && defined(HAVE_INT32_T) +typedef PY_UINT32_T ULong; +typedef PY_INT32_T Long; +#else +#error "Failed to find an exact-width 32-bit integer type" +#endif + +#if defined(HAVE_UINT64_T) +#define ULLong PY_UINT64_T +#else +#undef ULLong +#endif #undef DEBUG #ifdef Py_DEBUG @@ -273,16 +282,6 @@ typedef union { double d; ULong L[2]; } U; #define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) #define Big1 0xffffffff -/* Standard NaN used by _Py_dg_stdnan. */ - -#define NAN_WORD0 0x7ff80000 -#define NAN_WORD1 0 - -/* Bits of the representation of positive infinity. */ - -#define POSINF_WORD0 0x7ff00000 -#define POSINF_WORD1 0 - /* struct BCinfo is used to pass information from _Py_dg_strtod to bigcomp */ typedef struct BCinfo BCinfo; @@ -364,7 +363,7 @@ Balloc(int k) x = 1 << k; len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) /sizeof(double); - if (k <= Kmax && pmem_next - private_mem + len <= (Py_ssize_t)PRIVATE_mem) { + if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) { rv = (Bigint*)pmem_next; pmem_next += len; } @@ -448,8 +447,13 @@ static Bigint * multadd(Bigint *b, int m, int a) /* multiply by m and add a */ { int i, wds; +#ifdef ULLong ULong *x; ULLong carry, y; +#else + ULong carry, *x, y; + ULong xi, z; +#endif Bigint *b1; wds = b->wds; @@ -457,9 +461,17 @@ multadd(Bigint *b, int m, int a) /* multiply by m and add a */ i = 0; carry = a; do { +#ifdef ULLong y = *x * (ULLong)m + carry; carry = y >> 32; *x++ = (ULong)(y & FFFFFFFF); +#else + xi = *x; + y = (xi & 0xffff) * m + carry; + z = (xi >> 16) * m + (y >> 16); + carry = z >> 16; + *x++ = (z << 16) + (y & 0xffff); +#endif } while(++i < wds); if (carry) { @@ -620,7 +632,12 @@ mult(Bigint *a, Bigint *b) int k, wa, wb, wc; ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; ULong y; +#ifdef ULLong ULLong carry, z; +#else + ULong carry, z; + ULong z2; +#endif if ((!a->x[0] && a->wds == 1) || (!b->x[0] && b->wds == 1)) { c = Balloc(0); @@ -652,6 +669,7 @@ mult(Bigint *a, Bigint *b) xb = b->x; xbe = xb + wb; xc0 = c->x; +#ifdef ULLong for(; xb < xbe; xc0++) { if ((y = *xb++)) { x = xa; @@ -666,6 +684,39 @@ mult(Bigint *a, Bigint *b) *xc = (ULong)carry; } } +#else + for(; xb < xbe; xb++, xc0++) { + if (y = *xb & 0xffff) { + x = xa; + xc = xc0; + carry = 0; + do { + z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; + carry = z >> 16; + z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; + carry = z2 >> 16; + Storeinc(xc, z2, z); + } + while(x < xae); + *xc = carry; + } + if (y = *xb >> 16) { + x = xa; + xc = xc0; + carry = 0; + z2 = *xc; + do { + z = (*x & 0xffff) * y + (*xc >> 16) + carry; + carry = z >> 16; + Storeinc(xc, z, z2); + z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; + carry = z2 >> 16; + } + while(x < xae); + *xc = z2; + } + } +#endif for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; c->wds = wc; return c; @@ -686,7 +737,7 @@ pow5mult(Bigint *b, int k) { Bigint *b1, *p5, *p51; int i; - static const int p05[3] = { 5, 25, 125 }; + static int p05[3] = { 5, 25, 125 }; if ((i = k & 3)) { b = multadd(b, p05[i-1], 0); @@ -742,7 +793,7 @@ pow5mult(Bigint *b, int k) { Bigint *b1, *p5, *p51; int i; - static const int p05[3] = { 5, 25, 125 }; + static int p05[3] = { 5, 25, 125 }; if ((i = k & 3)) { b = multadd(b, p05[i-1], 0); @@ -874,7 +925,12 @@ diff(Bigint *a, Bigint *b) Bigint *c; int i, wa, wb; ULong *xa, *xae, *xb, *xbe, *xc; +#ifdef ULLong ULLong borrow, y; +#else + ULong borrow, y; + ULong z; +#endif i = cmp(a,b); if (!i) { @@ -905,6 +961,7 @@ diff(Bigint *a, Bigint *b) xbe = xb + wb; xc = c->x; borrow = 0; +#ifdef ULLong do { y = (ULLong)*xa++ - *xb++ - borrow; borrow = y >> 32 & (ULong)1; @@ -916,6 +973,23 @@ diff(Bigint *a, Bigint *b) borrow = y >> 32 & (ULong)1; *xc++ = (ULong)(y & FFFFFFFF); } +#else + do { + y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } + while(xb < xbe); + while(xa < xae) { + y = (*xa & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } +#endif while(!*--xc) wa--; c->wds = wa; @@ -1003,7 +1077,7 @@ sd2b(U *d, int scale, int *e) b = Balloc(1); if (b == NULL) return NULL; - + /* First construct b and e assuming that scale == 0. */ b->wds = 2; b->x[0] = word1(d); @@ -1160,7 +1234,12 @@ quorem(Bigint *b, Bigint *S) { int n; ULong *bx, *bxe, q, *sx, *sxe; +#ifdef ULLong ULLong borrow, carry, y, ys; +#else + ULong borrow, carry, y, ys; + ULong si, z, zs; +#endif n = S->wds; #ifdef DEBUG @@ -1182,11 +1261,23 @@ quorem(Bigint *b, Bigint *S) borrow = 0; carry = 0; do { +#ifdef ULLong ys = *sx++ * (ULLong)q + carry; carry = ys >> 32; y = *bx - (ys & FFFFFFFF) - borrow; borrow = y >> 32 & (ULong)1; *bx++ = (ULong)(y & FFFFFFFF); +#else + si = *sx++; + ys = (si & 0xffff) * q + carry; + zs = (si >> 16) * q + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#endif } while(sx <= sxe); if (!*bxe) { @@ -1203,11 +1294,23 @@ quorem(Bigint *b, Bigint *S) bx = b->x; sx = S->x; do { +#ifdef ULLong ys = *sx++ + carry; carry = ys >> 32; y = *bx - (ys & FFFFFFFF) - borrow; borrow = y >> 32 & (ULong)1; *bx++ = (ULong)(y & FFFFFFFF); +#else + si = *sx++; + ys = (si & 0xffff) + carry; + zs = (si >> 16) + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#endif } while(sx <= sxe); bx = b->x; @@ -1400,36 +1503,6 @@ bigcomp(U *rv, const char *s0, BCinfo *bc) return 0; } -/* Return a 'standard' NaN value. - - There are exactly two quiet NaNs that don't arise by 'quieting' signaling - NaNs (see IEEE 754-2008, section 6.2.1). If sign == 0, return the one whose - sign bit is cleared. Otherwise, return the one whose sign bit is set. -*/ - -double -_Py_dg_stdnan(int sign) -{ - U rv; - word0(&rv) = NAN_WORD0; - word1(&rv) = NAN_WORD1; - if (sign) - word0(&rv) |= Sign_bit; - return dval(&rv); -} - -/* Return positive or negative infinity, according to the given sign (0 for - * positive infinity, 1 for negative infinity). */ - -double -_Py_dg_infinity(int sign) -{ - U rv; - word0(&rv) = POSINF_WORD0; - word1(&rv) = POSINF_WORD1; - return sign ? -dval(&rv) : dval(&rv); -} - double _Py_dg_strtod(const char *s00, char **se) { @@ -1455,7 +1528,7 @@ _Py_dg_strtod(const char *s00, char **se) switch (c) { case '-': sign = 1; - /* fall through */ + /* no break */ case '+': c = *++s; } @@ -1524,7 +1597,7 @@ _Py_dg_strtod(const char *s00, char **se) switch (c) { case '-': esign = 1; - /* fall through */ + /* no break */ case '+': c = *++s; } @@ -1866,11 +1939,12 @@ _Py_dg_strtod(const char *s00, char **se) /* Scale bb, bd, bs by the appropriate powers of 2 and 5. */ if (bb5 > 0) { + Bigint *bb1; bs = pow5mult(bs, bb5); if (bs == NULL) { goto failed_malloc; } - Bigint *bb1 = mult(bs, bb); + bb1 = mult(bs, bb); Bfree(bb); bb = bb1; if (bb == NULL) { @@ -1981,7 +2055,7 @@ _Py_dg_strtod(const char *s00, char **se) + Exp_msk1 ; word1(&rv) = 0; - /* dsign = 0; */ + dsign = 0; break; } } @@ -2018,7 +2092,7 @@ _Py_dg_strtod(const char *s00, char **se) goto undfl; } } - /* dsign = 1 - dsign; */ + dsign = 1 - dsign; break; } if ((aadj = ratio(delta, bs)) <= 2.) { @@ -2173,7 +2247,7 @@ rv_alloc(int i) } static char * -nrv_alloc(const char *s, char **rve, int n) +nrv_alloc(char *s, char **rve, int n) { char *rv, *t; @@ -2412,7 +2486,7 @@ _Py_dg_dtoa(double dd, int mode, int ndigits, break; case 2: leftright = 0; - /* fall through */ + /* no break */ case 4: if (ndigits <= 0) ndigits = 1; @@ -2420,7 +2494,7 @@ _Py_dg_dtoa(double dd, int mode, int ndigits, break; case 3: leftright = 0; - /* fall through */ + /* no break */ case 5: i = ndigits + k + 1; ilim = i; |