mirror of
https://github.com/python/cpython.git
synced 2025-08-31 14:07:50 +00:00
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:
parent
ac4797a12e
commit
7a3bfc3a47
5 changed files with 337 additions and 77 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue