Left: | ||
Right: |
OLD | NEW |
---|---|
1 /**************************************************************** | 1 /**************************************************************** |
2 * | 2 * |
3 * The author of this software is David M. Gay. | 3 * The author of this software is David M. Gay. |
4 * | 4 * |
5 * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. | 5 * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. |
6 * | 6 * |
7 * Permission to use, copy, modify, and distribute this software for any | 7 * Permission to use, copy, modify, and distribute this software for any |
8 * purpose without fee is hereby granted, provided that this entire notice | 8 * purpose without fee is hereby granted, provided that this entire notice |
9 * is included in all copies of any software which is or includes a copy | 9 * is included in all copies of any software which is or includes a copy |
10 * or modification of this software and in all copies of the supporting | 10 * or modification of this software and in all copies of the supporting |
(...skipping 1288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1299 for(i = 0; i < nd0; i++) { | 1299 for(i = 0; i < nd0; i++) { |
1300 b = multadd(b, 10, 0); | 1300 b = multadd(b, 10, 0); |
1301 if (b == NULL) { | 1301 if (b == NULL) { |
1302 Bfree(d); | 1302 Bfree(d); |
1303 return -1; | 1303 return -1; |
1304 } | 1304 } |
1305 dd = *s0++ - '0' - quorem(b, d); | 1305 dd = *s0++ - '0' - quorem(b, d); |
1306 if (dd) | 1306 if (dd) |
1307 goto ret; | 1307 goto ret; |
1308 if (!b->x[0] && b->wds == 1) { | 1308 if (!b->x[0] && b->wds == 1) { |
1309 if (i < nd - 1) | 1309 if (i < nd - 1) |
dickinsm
2010/01/16 08:34:31
The next line assumes that at least one of the dig
| |
1310 dd = 1; | 1310 dd = 1; |
1311 goto ret; | 1311 goto ret; |
1312 } | 1312 } |
1313 } | 1313 } |
1314 s0++; | 1314 s0++; |
1315 for(; i < nd; i++) { | 1315 for(; i < nd; i++) { |
1316 b = multadd(b, 10, 0); | 1316 b = multadd(b, 10, 0); |
1317 if (b == NULL) { | 1317 if (b == NULL) { |
1318 Bfree(d); | 1318 Bfree(d); |
1319 return -1; | 1319 return -1; |
1320 } | 1320 } |
1321 dd = *s0++ - '0' - quorem(b, d); | 1321 dd = *s0++ - '0' - quorem(b, d); |
1322 if (dd) | 1322 if (dd) |
1323 goto ret; | 1323 goto ret; |
1324 if (!b->x[0] && b->wds == 1) { | 1324 if (!b->x[0] && b->wds == 1) { |
1325 if (i < nd - 1) | 1325 if (i < nd - 1) |
dickinsm
2010/01/16 08:34:31
Ditto for the next line.
| |
1326 dd = 1; | 1326 dd = 1; |
1327 goto ret; | 1327 goto ret; |
1328 } | 1328 } |
1329 } | 1329 } |
1330 if (b->x[0] || b->wds > 1) | 1330 if (b->x[0] || b->wds > 1) |
1331 dd = -1; | 1331 dd = -1; |
1332 ret: | 1332 ret: |
1333 Bfree(b); | 1333 Bfree(b); |
1334 Bfree(d); | 1334 Bfree(d); |
1335 if (dd > 0 || (dd == 0 && odd)) | 1335 if (dd > 0 || (dd == 0 && odd)) |
1336 dval(rv) += sulp(rv, bc); | 1336 dval(rv) += sulp(rv, bc); |
1337 return 0; | 1337 return 0; |
1338 } | 1338 } |
1339 | 1339 |
1340 double | 1340 double |
1341 _Py_dg_strtod(const char *s00, char **se) | 1341 _Py_dg_strtod(const char *s00, char **se) |
1342 { | 1342 { |
1343 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dp0, dp1, dplen, e, e1, error; | 1343 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1, error; |
1344 int esign, i, j, k, nd, nd0, nf, nz, nz0, sign; | 1344 int esign, i, j, k, nd, nd0, nf, nz, nz0, sign; |
1345 const char *s, *s0, *s1; | 1345 const char *s, *s0, *s1; |
1346 double aadj, aadj1; | 1346 double aadj, aadj1; |
1347 U aadj2, adj, rv, rv0; | 1347 U aadj2, adj, rv, rv0; |
1348 ULong y, z, L; | 1348 ULong y, z, L; |
1349 BCinfo bc; | 1349 BCinfo bc; |
1350 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; | 1350 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; |
1351 | 1351 |
1352 sign = nz0 = nz = dplen = 0; | 1352 sign = nz0 = nz = 0; |
1353 dval(&rv) = 0.; | 1353 dval(&rv) = 0.; |
1354 for(s = s00;;s++) switch(*s) { | 1354 for(s = s00;;s++) switch(*s) { |
1355 case '-': | 1355 case '-': |
1356 sign = 1; | 1356 sign = 1; |
1357 /* no break */ | 1357 /* no break */ |
1358 case '+': | 1358 case '+': |
1359 if (*++s) | 1359 if (*++s) |
1360 goto break2; | 1360 goto break2; |
1361 /* no break */ | 1361 /* no break */ |
1362 case 0: | 1362 case 0: |
(...skipping 18 matching lines...) Expand all Loading... | |
1381 goto ret; | 1381 goto ret; |
1382 } | 1382 } |
1383 s0 = s; | 1383 s0 = s; |
1384 y = z = 0; | 1384 y = z = 0; |
1385 for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) | 1385 for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) |
1386 if (nd < 9) | 1386 if (nd < 9) |
1387 y = 10*y + c - '0'; | 1387 y = 10*y + c - '0'; |
1388 else if (nd < 16) | 1388 else if (nd < 16) |
1389 z = 10*z + c - '0'; | 1389 z = 10*z + c - '0'; |
1390 nd0 = nd; | 1390 nd0 = nd; |
1391 dp0 = dp1 = s - s0; | |
1392 if (c == '.') { | 1391 if (c == '.') { |
1393 c = *++s; | 1392 c = *++s; |
1394 dp1 = s - s0; | |
1395 dplen = 1; | |
1396 if (!nd) { | 1393 if (!nd) { |
1397 for(; c == '0'; c = *++s) | 1394 for(; c == '0'; c = *++s) |
1398 nz++; | 1395 nz++; |
1399 if (c > '0' && c <= '9') { | 1396 if (c > '0' && c <= '9') { |
1400 s0 = s; | 1397 s0 = s; |
1401 nf += nz; | 1398 nf += nz; |
1402 nz = 0; | 1399 nz = 0; |
1403 goto have_dig; | 1400 goto have_dig; |
1404 } | 1401 } |
1405 goto dig_done; | 1402 goto dig_done; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1470 } | 1467 } |
1471 bc.e0 = e1 = e -= nf; | 1468 bc.e0 = e1 = e -= nf; |
1472 | 1469 |
1473 /* Now we have nd0 digits, starting at s0, followed by a | 1470 /* Now we have nd0 digits, starting at s0, followed by a |
1474 * decimal point, followed by nd-nd0 digits. The number we're | 1471 * decimal point, followed by nd-nd0 digits. The number we're |
1475 * after is the integer represented by those digits times | 1472 * after is the integer represented by those digits times |
1476 * 10**e */ | 1473 * 10**e */ |
1477 | 1474 |
1478 if (!nd0) | 1475 if (!nd0) |
1479 nd0 = nd; | 1476 nd0 = nd; |
1477 | |
1478 /* Summary of parsing results. The parsing stage gives values | |
1479 * s0, nd0, nd, e, y and z such that: | |
eric2
2010/01/15 22:41:28
Are these the only local variables that carry forw
dickinsm
2010/01/16 08:34:31
Agreed. I am interested in doing some more seriou
| |
1480 * | |
1481 * - nd >= nd0 >= 1 | |
1482 * | |
1483 * - the nd significant digits are in s0[0:nd0] and s0[nd0+1:nd+1] | |
1484 * (using the usual Python half-open slice notation) | |
1485 * | |
1486 * - the absolute value of the number represented by the original input | |
1487 * string is n * 10**e, where n is the integer represented by the | |
1488 * concatenation of s0[0:nd0] and s0[nd0+1:nd+1] | |
1489 * | |
1490 * - the first significant digit is nonzero | |
1491 * | |
1492 * - the last significant digit may or may not be nonzero; (some code | |
1493 * currently assumes that it's nonzero; this is a bug) | |
eric2
2010/01/15 22:41:28
Where is the "some code" that makes the assumption
dickinsm
2010/01/16 08:34:31
In this file. I've flagged those places with comm
| |
1494 * | |
1495 * - y contains the value represented by the first min(9, nd) | |
1496 * significant digits | |
1497 * | |
1498 * - if nd > 9, z contains the value represented by significant digits | |
1499 * with indices in [9, min(16, nd)). So y * 10**(min(16, nd) - 9) + z | |
1500 * gives the value represented by the first min(16, nd) sig. digits. | |
1501 */ | |
1502 | |
1480 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; | 1503 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; |
1481 dval(&rv) = y; | 1504 dval(&rv) = y; |
1482 if (k > 9) { | 1505 if (k > 9) { |
1483 dval(&rv) = tens[k - 9] * dval(&rv) + z; | 1506 dval(&rv) = tens[k - 9] * dval(&rv) + z; |
1484 } | 1507 } |
1485 bd0 = 0; | 1508 bd0 = 0; |
1486 if (nd <= DBL_DIG | 1509 if (nd <= DBL_DIG |
1487 && Flt_Rounds == 1 | 1510 && Flt_Rounds == 1 |
1488 ) { | 1511 ) { |
1489 if (!e) | 1512 if (!e) |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1586 /* Put digits into bd: true value = bd * 10^e */ | 1609 /* Put digits into bd: true value = bd * 10^e */ |
1587 | 1610 |
1588 bc.nd = nd; | 1611 bc.nd = nd; |
1589 bc.nd0 = nd0; /* Only needed if nd > STRTOD_DIGLIM, but done here */ | 1612 bc.nd0 = nd0; /* Only needed if nd > STRTOD_DIGLIM, but done here */ |
1590 /* to silence an erroneous warning about bc.nd0 */ | 1613 /* to silence an erroneous warning about bc.nd0 */ |
1591 /* possibly not being initialized. */ | 1614 /* possibly not being initialized. */ |
1592 if (nd > STRTOD_DIGLIM) { | 1615 if (nd > STRTOD_DIGLIM) { |
1593 /* ASSERT(STRTOD_DIGLIM >= 18); 18 == one more than the */ | 1616 /* ASSERT(STRTOD_DIGLIM >= 18); 18 == one more than the */ |
1594 /* minimum number of decimal digits to distinguish double values */ | 1617 /* minimum number of decimal digits to distinguish double values */ |
1595 /* in IEEE arithmetic. */ | 1618 /* in IEEE arithmetic. */ |
1596 i = j = 18; | 1619 |
1597 if (i > nd0) | 1620 /* Truncate input to 18 significant digits, then discard any trailing |
1598 j += dplen; | 1621 zeros on the result by updating nd, nd0, e and y suitably. (There's |
1599 for(;;) { | 1622 no need to update z; it's not reused beyond this point.) */ |
1600 if (--j <= dp1 && j >= dp0) | 1623 for (i = 18; i > 0; ) { |
1601 j = dp0 - 1; | 1624 /* scan back until we hit a nonzero digit. significant digit 'i' |
1602 if (s0[j] != '0') | 1625 is s0[i] if i < nd0, s0[i+1] if i >= nd0. */ |
1626 --i; | |
1627 if ((i < nd0 ? s0[i] : s0[i+1]) != '0') { | |
eric2
2010/01/15 22:41:28
It doesn't really make much difference, but I woul
dickinsm
2010/01/16 08:34:31
Will do. Thanks.
| |
1628 ++i; | |
1603 break; | 1629 break; |
1604 --i; | 1630 } |
1605 } | 1631 } |
1606 e += nd - i; | 1632 e += nd - i; |
1607 nd = i; | 1633 nd = i; |
1608 if (nd0 > nd) | 1634 if (nd0 > nd) |
1609 nd0 = nd; | 1635 nd0 = nd; |
1610 if (nd < 9) { /* must recompute y */ | 1636 if (nd < 9) { /* must recompute y */ |
1611 y = 0; | 1637 y = 0; |
1612 for(i = 0; i < nd0; ++i) | 1638 for(i = 0; i < nd0; ++i) |
1613 y = 10*y + s0[i] - '0'; | 1639 y = 10*y + s0[i] - '0'; |
1614 for(j = dp1; i < nd; ++i) | 1640 for(; i < nd; ++i) |
1615 y = 10*y + s0[j++] - '0'; | 1641 y = 10*y + s0[i+1] - '0'; |
1616 } | 1642 } |
1617 } | 1643 } |
1618 bd0 = s2b(s0, nd0, nd, y); | 1644 bd0 = s2b(s0, nd0, nd, y); |
1619 if (bd0 == NULL) | 1645 if (bd0 == NULL) |
1620 goto failed_malloc; | 1646 goto failed_malloc; |
1621 | 1647 |
1622 for(;;) { | 1648 for(;;) { |
1623 bd = Balloc(bd0->k); | 1649 bd = Balloc(bd0->k); |
1624 if (bd == NULL) { | 1650 if (bd == NULL) { |
1625 Bfree(bd0); | 1651 Bfree(bd0); |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1757 /* rv / 2^bc.scale = 2^(j - 1023 - bc.scale); use bigcomp if | 1783 /* rv / 2^bc.scale = 2^(j - 1023 - bc.scale); use bigcomp if |
1758 rv / 2^bc.scale >= 2^-1021. */ | 1784 rv / 2^bc.scale >= 2^-1021. */ |
1759 if (j - bc.scale >= 2) { | 1785 if (j - bc.scale >= 2) { |
1760 dval(&rv) -= 0.5 * sulp(&rv, &bc); | 1786 dval(&rv) -= 0.5 * sulp(&rv, &bc); |
1761 break; | 1787 break; |
1762 } | 1788 } |
1763 } | 1789 } |
1764 | 1790 |
1765 { | 1791 { |
1766 bc.nd = nd; | 1792 bc.nd = nd; |
1767 i = -1; /* Discarded digits make delta smaller. */ | 1793 i = -1; /* Discarded digits make delta smaller. */ |
dickinsm
2010/01/16 08:34:31
This code assumes that at least one of the discard
| |
1768 } | 1794 } |
1769 } | 1795 } |
1770 | 1796 |
1771 if (i < 0) { | 1797 if (i < 0) { |
1772 /* Error is less than half an ulp -- check for | 1798 /* Error is less than half an ulp -- check for |
1773 * special case of mantissa a power of two. | 1799 * special case of mantissa a power of two. |
1774 */ | 1800 */ |
1775 if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask | 1801 if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask |
1776 || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1 | 1802 || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1 |
1777 ) { | 1803 ) { |
(...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2649 Bfree(b); | 2675 Bfree(b); |
2650 if (s0) | 2676 if (s0) |
2651 _Py_dg_freedtoa(s0); | 2677 _Py_dg_freedtoa(s0); |
2652 return NULL; | 2678 return NULL; |
2653 } | 2679 } |
2654 #ifdef __cplusplus | 2680 #ifdef __cplusplus |
2655 } | 2681 } |
2656 #endif | 2682 #endif |
2657 | 2683 |
2658 #endif /* PY_NO_SHORT_FLOAT_REPR */ | 2684 #endif /* PY_NO_SHORT_FLOAT_REPR */ |
OLD | NEW |