summaryrefslogtreecommitdiffstats
path: root/Python/dtoa.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/dtoa.c')
-rw-r--r--Python/dtoa.c184
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;