Merged revisions 77691,77698,77713-77714 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r77691 | mark.dickinson | 2010-01-22 16:18:09 +0000 (Fri, 22 Jan 2010) | 1 line Correct typo in comment. ........ r77698 | mark.dickinson | 2010-01-22 17:04:07 +0000 (Fri, 22 Jan 2010) | 3 lines Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug in issue 7743). ........ r77713 | mark.dickinson | 2010-01-23 20:48:56 +0000 (Sat, 23 Jan 2010) | 3 lines Issue #7743: Add checks for zero inputs to the lshift and mult functions; this fixes the first bug described in issue #7743. ........ r77714 | mark.dickinson | 2010-01-23 21:25:53 +0000 (Sat, 23 Jan 2010) | 1 line dtoa.c fix from upstream that fixes incorrectly rounded results for certain subnormals that are also halfway cases. ........
This commit is contained in:
parent
53ab5cbcc7
commit
f41d29a8eb
193
Python/dtoa.c
193
Python/dtoa.c
|
@ -235,6 +235,7 @@ typedef union { double d; ULong L[2]; } U;
|
||||||
#define Bias 1023
|
#define Bias 1023
|
||||||
#define Emax 1023
|
#define Emax 1023
|
||||||
#define Emin (-1022)
|
#define Emin (-1022)
|
||||||
|
#define Etiny (-1074) /* smallest denormal is 2**Etiny */
|
||||||
#define Exp_1 0x3ff00000
|
#define Exp_1 0x3ff00000
|
||||||
#define Exp_11 0x3ff00000
|
#define Exp_11 0x3ff00000
|
||||||
#define Ebits 11
|
#define Ebits 11
|
||||||
|
@ -244,7 +245,6 @@ typedef union { double d; ULong L[2]; } U;
|
||||||
#define Bletch 0x10
|
#define Bletch 0x10
|
||||||
#define Bndry_mask 0xfffff
|
#define Bndry_mask 0xfffff
|
||||||
#define Bndry_mask1 0xfffff
|
#define Bndry_mask1 0xfffff
|
||||||
#define LSB 1
|
|
||||||
#define Sign_bit 0x80000000
|
#define Sign_bit 0x80000000
|
||||||
#define Log2P 1
|
#define Log2P 1
|
||||||
#define Tiny0 0
|
#define Tiny0 0
|
||||||
|
@ -622,6 +622,15 @@ mult(Bigint *a, Bigint *b)
|
||||||
ULong z2;
|
ULong z2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if ((!a->x[0] && a->wds == 1) || (!b->x[0] && b->wds == 1)) {
|
||||||
|
c = Balloc(0);
|
||||||
|
if (c == NULL)
|
||||||
|
return NULL;
|
||||||
|
c->wds = 1;
|
||||||
|
c->x[0] = 0;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
if (a->wds < b->wds) {
|
if (a->wds < b->wds) {
|
||||||
c = a;
|
c = a;
|
||||||
a = b;
|
a = b;
|
||||||
|
@ -820,6 +829,9 @@ lshift(Bigint *b, int k)
|
||||||
Bigint *b1;
|
Bigint *b1;
|
||||||
ULong *x, *x1, *xe, z;
|
ULong *x, *x1, *xe, z;
|
||||||
|
|
||||||
|
if (!k || (!b->x[0] && b->wds == 1))
|
||||||
|
return b;
|
||||||
|
|
||||||
n = k >> 5;
|
n = k >> 5;
|
||||||
k1 = b->k;
|
k1 = b->k;
|
||||||
n1 = n + b->wds + 1;
|
n1 = n + b->wds + 1;
|
||||||
|
@ -1019,6 +1031,76 @@ b2d(Bigint *a, int *e)
|
||||||
return dval(&d);
|
return dval(&d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Convert a scaled double to a Bigint plus an exponent. Similar to d2b,
|
||||||
|
except that it accepts the scale parameter used in _Py_dg_strtod (which
|
||||||
|
should be either 0 or 2*P), and the normalization for the return value is
|
||||||
|
different (see below). On input, d should be finite and nonnegative, and d
|
||||||
|
/ 2**scale should be exactly representable as an IEEE 754 double.
|
||||||
|
|
||||||
|
Returns a Bigint b and an integer e such that
|
||||||
|
|
||||||
|
dval(d) / 2**scale = b * 2**e.
|
||||||
|
|
||||||
|
Unlike d2b, b is not necessarily odd: b and e are normalized so
|
||||||
|
that either 2**(P-1) <= b < 2**P and e >= Etiny, or b < 2**P
|
||||||
|
and e == Etiny. This applies equally to an input of 0.0: in that
|
||||||
|
case the return values are b = 0 and e = Etiny.
|
||||||
|
|
||||||
|
The above normalization ensures that for all possible inputs d,
|
||||||
|
2**e gives ulp(d/2**scale).
|
||||||
|
|
||||||
|
Returns NULL on failure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static Bigint *
|
||||||
|
sd2b(U *d, int scale, int *e)
|
||||||
|
{
|
||||||
|
Bigint *b;
|
||||||
|
|
||||||
|
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);
|
||||||
|
b->x[1] = word0(d) & Frac_mask;
|
||||||
|
*e = Etiny - 1 + (int)((word0(d) & Exp_mask) >> Exp_shift);
|
||||||
|
if (*e < Etiny)
|
||||||
|
*e = Etiny;
|
||||||
|
else
|
||||||
|
b->x[1] |= Exp_msk1;
|
||||||
|
|
||||||
|
/* Now adjust for scale, provided that b != 0. */
|
||||||
|
if (scale && (b->x[0] || b->x[1])) {
|
||||||
|
*e -= scale;
|
||||||
|
if (*e < Etiny) {
|
||||||
|
scale = Etiny - *e;
|
||||||
|
*e = Etiny;
|
||||||
|
/* We can't shift more than P-1 bits without shifting out a 1. */
|
||||||
|
assert(0 < scale && scale <= P - 1);
|
||||||
|
if (scale >= 32) {
|
||||||
|
/* The bits shifted out should all be zero. */
|
||||||
|
assert(b->x[0] == 0);
|
||||||
|
b->x[0] = b->x[1];
|
||||||
|
b->x[1] = 0;
|
||||||
|
scale -= 32;
|
||||||
|
}
|
||||||
|
if (scale) {
|
||||||
|
/* The bits shifted out should all be zero. */
|
||||||
|
assert(b->x[0] << (32 - scale) == 0);
|
||||||
|
b->x[0] = (b->x[0] >> scale) | (b->x[1] << (32 - scale));
|
||||||
|
b->x[1] >>= scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Ensure b is normalized. */
|
||||||
|
if (!b->x[1])
|
||||||
|
b->wds = 1;
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert a double to a Bigint plus an exponent. Return NULL on failure.
|
/* Convert a double to a Bigint plus an exponent. Return NULL on failure.
|
||||||
|
|
||||||
Given a finite nonzero double d, return an odd Bigint b and exponent *e
|
Given a finite nonzero double d, return an odd Bigint b and exponent *e
|
||||||
|
@ -1028,7 +1110,6 @@ b2d(Bigint *a, int *e)
|
||||||
If d is zero, then b == 0, *e == -1010, *bbits = 0.
|
If d is zero, then b == 0, *e == -1010, *bbits = 0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static Bigint *
|
static Bigint *
|
||||||
d2b(U *d, int *e, int *bits)
|
d2b(U *d, int *e, int *bits)
|
||||||
{
|
{
|
||||||
|
@ -1299,45 +1380,29 @@ static int
|
||||||
bigcomp(U *rv, const char *s0, BCinfo *bc)
|
bigcomp(U *rv, const char *s0, BCinfo *bc)
|
||||||
{
|
{
|
||||||
Bigint *b, *d;
|
Bigint *b, *d;
|
||||||
int b2, bbits, d2, dd, i, nd, nd0, odd, p2, p5;
|
int b2, d2, dd, i, nd, nd0, odd, p2, p5;
|
||||||
|
|
||||||
dd = 0; /* silence compiler warning about possibly unused variable */
|
dd = 0; /* silence compiler warning about possibly unused variable */
|
||||||
nd = bc->nd;
|
nd = bc->nd;
|
||||||
nd0 = bc->nd0;
|
nd0 = bc->nd0;
|
||||||
p5 = nd + bc->e0;
|
p5 = nd + bc->e0;
|
||||||
if (rv->d == 0.) {
|
b = sd2b(rv, bc->scale, &p2);
|
||||||
/* special case because d2b doesn't handle 0.0 */
|
|
||||||
b = i2b(0);
|
|
||||||
if (b == NULL)
|
|
||||||
return -1;
|
|
||||||
p2 = Emin - P + 1; /* = -1074 for IEEE 754 binary64 */
|
|
||||||
bbits = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
b = d2b(rv, &p2, &bbits);
|
|
||||||
if (b == NULL)
|
|
||||||
return -1;
|
|
||||||
p2 -= bc->scale;
|
|
||||||
}
|
|
||||||
/* now rv/2^(bc->scale) = b * 2**p2, and b has bbits significant bits */
|
|
||||||
|
|
||||||
/* Replace (b, p2) by (b << i, p2 - i), with i the largest integer such
|
|
||||||
that b << i has at most P significant bits and p2 - i >= Emin - P +
|
|
||||||
1. */
|
|
||||||
i = P - bbits;
|
|
||||||
if (i > p2 - (Emin - P + 1))
|
|
||||||
i = p2 - (Emin - P + 1);
|
|
||||||
/* increment i so that we shift b by an extra bit; then or-ing a 1 into
|
|
||||||
the lsb of b gives us rv/2^(bc->scale) + 0.5ulp. */
|
|
||||||
b = lshift(b, ++i);
|
|
||||||
if (b == NULL)
|
if (b == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* record whether the lsb of rv/2^(bc->scale) is odd: in the exact halfway
|
/* record whether the lsb of rv/2^(bc->scale) is odd: in the exact halfway
|
||||||
case, this is used for round to even. */
|
case, this is used for round to even. */
|
||||||
odd = b->x[0] & 2;
|
odd = b->x[0] & 1;
|
||||||
b->x[0] |= 1;
|
|
||||||
|
|
||||||
p2 -= p5 + i;
|
/* left shift b by 1 bit and or a 1 into the least significant bit;
|
||||||
|
this gives us b * 2**p2 = rv/2^(bc->scale) + 0.5 ulp. */
|
||||||
|
b = lshift(b, 1);
|
||||||
|
if (b == NULL)
|
||||||
|
return -1;
|
||||||
|
b->x[0] |= 1;
|
||||||
|
p2--;
|
||||||
|
|
||||||
|
p2 -= p5;
|
||||||
d = i2b(1);
|
d = i2b(1);
|
||||||
if (d == NULL) {
|
if (d == NULL) {
|
||||||
Bfree(b);
|
Bfree(b);
|
||||||
|
@ -1425,8 +1490,8 @@ bigcomp(U *rv, const char *s0, BCinfo *bc)
|
||||||
double
|
double
|
||||||
_Py_dg_strtod(const char *s00, char **se)
|
_Py_dg_strtod(const char *s00, char **se)
|
||||||
{
|
{
|
||||||
int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, e, e1, error;
|
int bb2, bb5, bbe, bd2, bd5, bs2, c, dsign, e, e1, error;
|
||||||
int esign, i, j, k, lz, nd, nd0, sign;
|
int esign, i, j, k, lz, nd, nd0, odd, sign;
|
||||||
const char *s, *s0, *s1;
|
const char *s, *s0, *s1;
|
||||||
double aadj, aadj1;
|
double aadj, aadj1;
|
||||||
U aadj2, adj, rv, rv0;
|
U aadj2, adj, rv, rv0;
|
||||||
|
@ -1786,13 +1851,17 @@ _Py_dg_strtod(const char *s00, char **se)
|
||||||
goto failed_malloc;
|
goto failed_malloc;
|
||||||
}
|
}
|
||||||
Bcopy(bd, bd0);
|
Bcopy(bd, bd0);
|
||||||
bb = d2b(&rv, &bbe, &bbbits); /* rv = bb * 2^bbe */
|
bb = sd2b(&rv, bc.scale, &bbe); /* srv = bb * 2^bbe */
|
||||||
if (bb == NULL) {
|
if (bb == NULL) {
|
||||||
Bfree(bd);
|
Bfree(bd);
|
||||||
Bfree(bd0);
|
Bfree(bd0);
|
||||||
goto failed_malloc;
|
goto failed_malloc;
|
||||||
}
|
}
|
||||||
/* tdv = bd * 10^e; srv = bb * 2^(bbe - scale) */
|
/* Record whether lsb of bb is odd, in case we need this
|
||||||
|
for the round-to-even step later. */
|
||||||
|
odd = bb->x[0] & 1;
|
||||||
|
|
||||||
|
/* tdv = bd * 10**e; srv = bb * 2**bbe */
|
||||||
bs = i2b(1);
|
bs = i2b(1);
|
||||||
if (bs == NULL) {
|
if (bs == NULL) {
|
||||||
Bfree(bb);
|
Bfree(bb);
|
||||||
|
@ -1813,44 +1882,28 @@ _Py_dg_strtod(const char *s00, char **se)
|
||||||
bb2 += bbe;
|
bb2 += bbe;
|
||||||
else
|
else
|
||||||
bd2 -= bbe;
|
bd2 -= bbe;
|
||||||
|
|
||||||
/* At this stage e = bd2 - bb2 + bbe = bd5 - bb5, so:
|
|
||||||
|
|
||||||
tdv = bd * 2^(bbe + bd2 - bb2) * 5^(bd5 - bb5)
|
|
||||||
srv = bb * 2^(bbe - scale).
|
|
||||||
|
|
||||||
Compute j such that
|
|
||||||
|
|
||||||
0.5 ulp(srv) = 2^(bbe - scale - j)
|
|
||||||
*/
|
|
||||||
|
|
||||||
bs2 = bb2;
|
bs2 = bb2;
|
||||||
j = bbe - bc.scale;
|
bb2++;
|
||||||
i = j + bbbits - 1; /* logb(rv) */
|
bd2++;
|
||||||
if (i < Emin) /* denormal */
|
|
||||||
j += P - Emin;
|
|
||||||
else
|
|
||||||
j = P + 1 - bbbits;
|
|
||||||
|
|
||||||
/* Now we have:
|
/* At this stage bd5 - bb5 == e == bd2 - bb2 + bbe, bb2 - bs2 == 1,
|
||||||
|
and bs == 1, so:
|
||||||
|
|
||||||
M * tdv = bd * 2^(bd2 + scale + j) * 5^bd5
|
tdv == bd * 10**e = bd * 2**(bbe - bb2 + bd2) * 5**(bd5 - bb5)
|
||||||
M * srv = bb * 2^(bb2 + j) * 5^bb5
|
srv == bb * 2**bbe = bb * 2**(bbe - bb2 + bb2)
|
||||||
M * 0.5 ulp(srv) = 2^bs2 * 5^bb5
|
0.5 ulp(srv) == 2**(bbe-1) = bs * 2**(bbe - bb2 + bs2)
|
||||||
|
|
||||||
where M is the constant (currently) represented by 2^(j + scale +
|
It follows that:
|
||||||
bb2 - bbe) * 5^bb5.
|
|
||||||
|
M * tdv = bd * 2**bd2 * 5**bd5
|
||||||
|
M * srv = bb * 2**bb2 * 5**bb5
|
||||||
|
M * 0.5 ulp(srv) = bs * 2**bs2 * 5**bb5
|
||||||
|
|
||||||
|
for some constant M. (Actually, M == 2**(bb2 - bbe) * 5**bb5, but
|
||||||
|
this fact is not needed below.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bb2 += j;
|
/* Remove factor of 2**i, where i = min(bb2, bd2, bs2). */
|
||||||
bd2 += j;
|
|
||||||
bd2 += bc.scale;
|
|
||||||
|
|
||||||
/* After the adjustments above, tdv, srv and 0.5 ulp(srv) are
|
|
||||||
proportional to: bd * 2^bd2 * 5^bd5, bb * 2^bb2 * 5^bb5, and
|
|
||||||
bs * 2^bs2 * 5^bb5, respectively. */
|
|
||||||
|
|
||||||
/* Remove excess powers of 2. i = min(bb2, bd2, bs2). */
|
|
||||||
i = bb2 < bd2 ? bb2 : bd2;
|
i = bb2 < bd2 ? bb2 : bd2;
|
||||||
if (i > bs2)
|
if (i > bs2)
|
||||||
i = bs2;
|
i = bs2;
|
||||||
|
@ -2028,12 +2081,12 @@ _Py_dg_strtod(const char *s00, char **se)
|
||||||
word1(&rv) = 0xffffffff;
|
word1(&rv) = 0xffffffff;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!(word1(&rv) & LSB))
|
if (!odd)
|
||||||
break;
|
break;
|
||||||
if (dsign)
|
if (dsign)
|
||||||
dval(&rv) += ulp(&rv);
|
dval(&rv) += sulp(&rv, &bc);
|
||||||
else {
|
else {
|
||||||
dval(&rv) -= ulp(&rv);
|
dval(&rv) -= sulp(&rv, &bc);
|
||||||
if (!dval(&rv)) {
|
if (!dval(&rv)) {
|
||||||
if (bc.nd >nd)
|
if (bc.nd >nd)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -104,7 +104,7 @@ _PyOS_ascii_strtod(const char *nptr, char **endptr)
|
||||||
_Py_SET_53BIT_PRECISION_END;
|
_Py_SET_53BIT_PRECISION_END;
|
||||||
|
|
||||||
if (*endptr == nptr)
|
if (*endptr == nptr)
|
||||||
/* string might represent and inf or nan */
|
/* string might represent an inf or nan */
|
||||||
result = _Py_parse_inf_or_nan(nptr, endptr);
|
result = _Py_parse_inf_or_nan(nptr, endptr);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
Loading…
Reference in New Issue