@@ -315,9 +315,11 @@ PyLong_FromLongLong(ival)
315315#else
316316 if ( ival <= (long long )LONG_MAX ) {
317317 return PyLong_FromLong ( (long )ival );
318- } else if ( ival <= (unsigned long long )ULONG_MAX ) {
318+ }
319+ else if ( ival <= (unsigned long long )ULONG_MAX ) {
319320 return PyLong_FromUnsignedLong ( (unsigned long )ival );
320- } else {
321+ }
322+ else {
321323 /* Assume a C long long fits in at most 10 'digits'.
322324 * Should be OK if we're assuming long fits in 5.
323325 */
@@ -359,7 +361,8 @@ PyLong_FromUnsignedLongLong(ival)
359361#else
360362 if ( ival <= (unsigned long long )ULONG_MAX ) {
361363 return PyLong_FromUnsignedLong ( (unsigned long )ival );
362- } else {
364+ }
365+ else {
363366 /* Assume a C long fits in at most 10 'digits'. */
364367 PyLongObject * v = _PyLong_New (10 );
365368
@@ -572,30 +575,71 @@ long_format(aa, base)
572575 if (a -> ob_size < 0 )
573576 sign = '-' ;
574577
575- Py_INCREF (a );
576- do {
577- digit rem ;
578- PyLongObject * temp = divrem1 (a , (digit )base , & rem );
579- if (temp == NULL ) {
580- Py_DECREF (a );
581- Py_DECREF (str );
582- return NULL ;
578+ if (a -> ob_size == 0 ) {
579+ * -- p = '0' ;
580+ }
581+ else if ((base & (base - 1 )) == 0 ) {
582+ /* JRH: special case for power-of-2 bases */
583+ twodigits temp = a -> ob_digit [0 ];
584+ int bitsleft = SHIFT ;
585+ int rem ;
586+ int last = abs (a -> ob_size );
587+ int basebits = 1 ;
588+ i = base ;
589+ while ((i >>= 1 ) > 1 ) ++ basebits ;
590+
591+ i = 0 ;
592+ for (;;) {
593+ while (bitsleft >= basebits ) {
594+ if ((temp == 0 ) && (i >= last - 1 )) break ;
595+ rem = temp & (base - 1 );
596+ if (rem < 10 )
597+ rem += '0' ;
598+ else
599+ rem += 'A' - 10 ;
600+ assert (p > PyString_AS_STRING (str ));
601+ * -- p = (char ) rem ;
602+ bitsleft -= basebits ;
603+ temp >>= basebits ;
604+ }
605+ if (++ i >= last ) {
606+ if (temp == 0 ) break ;
607+ bitsleft = 99 ;
608+ /* loop again to pick up final digits */
609+ }
610+ else {
611+ temp = (a -> ob_digit [i ] << bitsleft ) | temp ;
612+ bitsleft += SHIFT ;
613+ }
583614 }
584- if (rem < 10 )
585- rem += '0' ;
586- else
587- rem += 'A' - 10 ;
588- assert (p > PyString_AS_STRING (str ));
589- * -- p = (char ) rem ;
590- Py_DECREF (a );
591- a = temp ;
592- SIGCHECK ({
615+ }
616+ else {
617+ Py_INCREF (a );
618+ do {
619+ digit rem ;
620+ PyLongObject * temp = divrem1 (a , (digit )base , & rem );
621+ if (temp == NULL ) {
622+ Py_DECREF (a );
623+ Py_DECREF (str );
624+ return NULL ;
625+ }
626+ if (rem < 10 )
627+ rem += '0' ;
628+ else
629+ rem += 'A' - 10 ;
630+ assert (p > PyString_AS_STRING (str ));
631+ * -- p = (char ) rem ;
593632 Py_DECREF (a );
594- Py_DECREF (str );
595- return NULL ;
596- })
597- } while (ABS (a -> ob_size ) != 0 );
598- Py_DECREF (a );
633+ a = temp ;
634+ SIGCHECK ({
635+ Py_DECREF (a );
636+ Py_DECREF (str );
637+ return NULL ;
638+ })
639+ } while (ABS (a -> ob_size ) != 0 );
640+ Py_DECREF (a );
641+ }
642+
599643 if (base == 8 ) {
600644 if (size_a != 0 )
601645 * -- p = '0' ;
@@ -723,7 +767,8 @@ long_divrem(a, b, pdiv, prem)
723767 PyLongObject * z ;
724768
725769 if (size_b == 0 ) {
726- PyErr_SetString (PyExc_ZeroDivisionError , "long division or modulo" );
770+ PyErr_SetString (PyExc_ZeroDivisionError ,
771+ "long division or modulo" );
727772 return -1 ;
728773 }
729774 if (size_a < size_b ||
@@ -1520,17 +1565,6 @@ long_bitwise(a, op, b)
15201565 maskb = 0 ;
15211566 }
15221567
1523- size_a = a -> ob_size ;
1524- size_b = b -> ob_size ;
1525- size_z = MAX (size_a , size_b );
1526- z = _PyLong_New (size_z );
1527- if (a == NULL || b == NULL || z == NULL ) {
1528- Py_XDECREF (a );
1529- Py_XDECREF (b );
1530- Py_XDECREF (z );
1531- return NULL ;
1532- }
1533-
15341568 negz = 0 ;
15351569 switch (op ) {
15361570 case '^' :
@@ -1557,6 +1591,31 @@ long_bitwise(a, op, b)
15571591 break ;
15581592 }
15591593
1594+ /* JRH: The original logic here was to allocate the result value (z)
1595+ as the longer of the two operands. However, there are some cases
1596+ where the result is guaranteed to be shorter than that: AND of two
1597+ positives, OR of two negatives: use the shorter number. AND with
1598+ mixed signs: use the positive number. OR with mixed signs: use the
1599+ negative number. After the transformations above, op will be '&'
1600+ iff one of these cases applies, and mask will be non-0 for operands
1601+ whose length should be ignored.
1602+ */
1603+
1604+ size_a = a -> ob_size ;
1605+ size_b = b -> ob_size ;
1606+ size_z = op == '&'
1607+ ? (maska
1608+ ? size_b
1609+ : (maskb ? size_a : MIN (size_a , size_b )))
1610+ : MAX (size_a , size_b );
1611+ z = _PyLong_New (size_z );
1612+ if (a == NULL || b == NULL || z == NULL ) {
1613+ Py_XDECREF (a );
1614+ Py_XDECREF (b );
1615+ Py_XDECREF (z );
1616+ return NULL ;
1617+ }
1618+
15601619 for (i = 0 ; i < size_z ; ++ i ) {
15611620 diga = (i < size_a ? a -> ob_digit [i ] : 0 ) ^ maska ;
15621621 digb = (i < size_b ? b -> ob_digit [i ] : 0 ) ^ maskb ;
0 commit comments