[Python-checkins] CVS: python/dist/src/Objects longobject.c,1.72,1.73
Tim Peters
tim_one@users.sourceforge.net
Mon, 11 Jun 2001 18:22:24 -0700
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv15300/python/dist/src/Objects
Modified Files:
longobject.c
Log Message:
Added q/Q standard (x-platform 8-byte ints) mode in struct module.
This completes the q/Q project.
longobject.c _PyLong_AsByteArray: The original code had a gross bug:
the most-significant Python digit doesn't necessarily have SHIFT
significant bits, and you really need to count how many copies of the sign
bit it has else spurious overflow errors result.
test_struct.py: This now does exhaustive std q/Q testing at, and on both
sides of, all relevant power-of-2 boundaries, both positive and negative.
NEWS: Added brief dict news while I was at it.
Index: longobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v
retrieving revision 1.72
retrieving revision 1.73
diff -C2 -r1.72 -r1.73
*** longobject.c 2001/06/11 21:23:58 1.72
--- longobject.c 2001/06/12 01:22:22 1.73
***************
*** 365,368 ****
--- 365,369 ----
carry = do_twos_comp ? 1 : 0;
for (i = 0; i < ndigits; ++i) {
+ unsigned int oldaccumbits = accumbits;
twodigits thisdigit = v->ob_digit[i];
if (do_twos_comp) {
***************
*** 371,382 ****
thisdigit &= MASK;
}
/* Because we're going LSB to MSB, thisdigit is more
significant than what's already in accum, so needs to be
prepended to accum. */
! accum |= thisdigit << accumbits;
! accumbits += SHIFT;
/* Store as many bytes as possible. */
! assert(accumbits >= 8);
! do {
if (j >= n)
goto Overflow;
--- 372,395 ----
thisdigit &= MASK;
}
+ if (i < ndigits - 1)
+ accumbits += SHIFT;
+ else {
+ /* The most-significant digit may be partly empty. */
+ twodigits bitmask = 1 << (SHIFT - 1);
+ twodigits signbit = do_twos_comp << (SHIFT - 1);
+ unsigned int nsignbits = 0;
+ while ((thisdigit & bitmask) == signbit && bitmask) {
+ ++nsignbits;
+ bitmask >>= 1;
+ signbit >>= 1;
+ }
+ accumbits += SHIFT - nsignbits;
+ }
/* Because we're going LSB to MSB, thisdigit is more
significant than what's already in accum, so needs to be
prepended to accum. */
! accum |= thisdigit << oldaccumbits;
/* Store as many bytes as possible. */
! while (accumbits >= 8) {
if (j >= n)
goto Overflow;
***************
*** 386,390 ****
accumbits -= 8;
accum >>= 8;
! } while (accumbits >= 8);
}
--- 399,403 ----
accumbits -= 8;
accum >>= 8;
! }
}
***************
*** 392,396 ****
assert(accumbits < 8);
assert(carry == 0); /* else do_twos_comp and *every* digit was 0 */
! if (accum) {
if (j >= n)
goto Overflow;
--- 405,409 ----
assert(accumbits < 8);
assert(carry == 0); /* else do_twos_comp and *every* digit was 0 */
! if (accumbits > 0) {
if (j >= n)
goto Overflow;