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.
This commit is contained in:
Tim Peters 2001-06-12 01:22:22 +00:00
parent ac4797a12e
commit 7a3bfc3a47
5 changed files with 337 additions and 77 deletions

View file

@ -364,20 +364,33 @@ _PyLong_AsByteArray(PyLongObject* v,
accumbits = 0;
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) {
thisdigit = (thisdigit ^ MASK) + carry;
carry = thisdigit >> SHIFT;
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 << accumbits;
accumbits += SHIFT;
accum |= thisdigit << oldaccumbits;
/* Store as many bytes as possible. */
assert(accumbits >= 8);
do {
while (accumbits >= 8) {
if (j >= n)
goto Overflow;
++j;
@ -385,13 +398,13 @@ _PyLong_AsByteArray(PyLongObject* v,
p += pincr;
accumbits -= 8;
accum >>= 8;
} while (accumbits >= 8);
}
}
/* Store the straggler (if any). */
assert(accumbits < 8);
assert(carry == 0); /* else do_twos_comp and *every* digit was 0 */
if (accum) {
if (accumbits > 0) {
if (j >= n)
goto Overflow;
++j;