@@ -24,10 +24,20 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2424
2525/* Long (arbitrary precision) integer object implementation */
2626
27+ /* XXX The functional organization of this file is terrible */
28+
2729#include "allobjects.h"
2830#include "longintrepr.h"
2931#include <assert.h>
3032
33+ static int ticker ; /* XXX Could be shared with ceval? */
34+
35+ #define INTRCHECK (block ) \
36+ if (--ticker < 0) { \
37+ ticker = 100; \
38+ if (intrcheck()) { block; } \
39+ }
40+
3141/* Normalize (remove leading zeros from) a long int object.
3242 Doesn't attempt to free the storage--in most cases, due to the nature
3343 of the algorithms used, this could save at most be one word anyway. */
@@ -146,7 +156,7 @@ dgetlongvalue(vv)
146156longobject *
147157mul1 (a , n )
148158 longobject * a ;
149- digit n ;
159+ wdigit n ;
150160{
151161 return muladd1 (a , n , (digit )0 );
152162}
@@ -156,8 +166,8 @@ mul1(a, n)
156166longobject *
157167muladd1 (a , n , extra )
158168 longobject * a ;
159- digit n ;
160- digit extra ;
169+ wdigit n ;
170+ wdigit extra ;
161171{
162172 int size_a = ABS (a -> ob_size );
163173 longobject * z = alloclongobject (size_a + 1 );
@@ -182,7 +192,7 @@ muladd1(a, n, extra)
182192longobject *
183193divrem1 (a , n , prem )
184194 longobject * a ;
185- digit n ;
195+ wdigit n ;
186196 digit * prem ;
187197{
188198 int size = ABS (a -> ob_size );
@@ -253,12 +263,12 @@ long_format(a, base)
253263 * -- p = rem ;
254264 DECREF (a );
255265 a = temp ;
256- if ( a -> ob_size >= INTRLIMIT && intrcheck ()) {
266+ INTRCHECK ( {
257267 DECREF (a );
258268 DECREF (str );
259269 err_set (KeyboardInterrupt );
260270 return NULL ;
261- }
271+ })
262272 } while (a -> ob_size != 0 );
263273 DECREF (a );
264274 if (sign )
@@ -342,7 +352,8 @@ long_divrem(a, b, prem)
342352 return NULL ;
343353 }
344354 if (size_a < size_b ||
345- size_a == size_b && a -> ob_digit [size_a - 1 ] < b -> ob_digit [size_b - 1 ]) {
355+ size_a == size_b &&
356+ a -> ob_digit [size_a - 1 ] < b -> ob_digit [size_b - 1 ]) {
346357 /* |a| < |b|. */
347358 if (prem != NULL ) {
348359 INCREF (a );
@@ -376,7 +387,7 @@ long_divrem(a, b, prem)
376387 return z ;
377388}
378389
379- /* True unsigned long division with remainder */
390+ /* Unsigned long division with remainder -- the algorithm */
380391
381392static longobject *
382393x_divrem (v1 , w1 , prem )
@@ -399,7 +410,7 @@ x_divrem(v1, w1, prem)
399410 }
400411
401412 assert (size_v >= size_w && size_w > 1 ); /* Assert checks by div() */
402- assert (v -> refcnt == 1 ); /* Since v will be used as accumulator! */
413+ assert (v -> ob_refcnt == 1 ); /* Since v will be used as accumulator! */
403414 assert (size_w == ABS (w -> ob_size )); /* That's how d was calculated */
404415
405416 size_v = ABS (v -> ob_size );
@@ -408,15 +419,15 @@ x_divrem(v1, w1, prem)
408419 for (j = size_v , k = a -> ob_size - 1 ; a != NULL && k >= 0 ; -- j , -- k ) {
409420 digit vj = (j >= size_v ) ? 0 : v -> ob_digit [j ];
410421 twodigits q ;
411- long carry = 0 ; /* Signed! long! */
422+ stwodigits carry = 0 ;
412423 int i ;
413424
414- if ( size_v >= INTRLIMIT && intrcheck ()) {
425+ INTRCHECK ( {
415426 DECREF (a );
416427 a = NULL ;
417428 err_set (KeyboardInterrupt );
418429 break ;
419- }
430+ })
420431 if (vj == w -> ob_digit [size_w - 1 ])
421432 q = MASK ;
422433 else
@@ -713,11 +724,11 @@ long_mul(a, w)
713724 twodigits f = a -> ob_digit [i ];
714725 int j ;
715726
716- if ( z -> ob_size >= INTRLIMIT && intrcheck ()) {
727+ INTRCHECK ( {
717728 DECREF (z );
718729 err_set (KeyboardInterrupt );
719730 return NULL ;
720- }
731+ })
721732 for (j = 0 ; j < size_b ; ++ j ) {
722733 carry += z -> ob_digit [i + j ] + b -> ob_digit [j ] * f ;
723734 z -> ob_digit [i + j ] = carry & MASK ;
@@ -781,7 +792,8 @@ long_rem(v, w)
781792 13 -10 3 -7
782793 -13 -10 -3 -3
783794 So, to get from rem to mod, we have to add b if a and b
784- have different signs. */
795+ have different signs. We then subtract one from the 'div'
796+ part of the outcome to keep the invariant intact. */
785797
786798static object *
787799long_divmod (v , w )
@@ -800,13 +812,24 @@ long_divmod(v, w)
800812 return NULL ;
801813 }
802814 if ((v -> ob_size < 0 ) != (((longobject * )w )-> ob_size < 0 )) {
803- longobject * temp = (longobject * ) long_add (rem , w );
815+ longobject * temp ;
816+ longobject * one ;
817+ temp = (longobject * ) long_add (rem , w );
804818 DECREF (rem );
805- rem = temp ; /* XXX ??? was rem = b ??? */
819+ rem = temp ;
806820 if (rem == NULL ) {
807821 DECREF (div );
808822 return NULL ;
809823 }
824+ one = (longobject * ) newlongobject (1L );
825+ if (one == NULL ||
826+ (temp = (longobject * ) long_sub (div , one )) == NULL ) {
827+ DECREF (rem );
828+ DECREF (div );
829+ return NULL ;
830+ }
831+ DECREF (div );
832+ div = temp ;
810833 }
811834 z = newtupleobject (2 );
812835 if (z != NULL ) {
@@ -869,6 +892,13 @@ long_abs(v)
869892 return long_pos (v );
870893}
871894
895+ static int
896+ long_nonzero (v )
897+ longobject * v ;
898+ {
899+ return v -> ob_size != 0 ;
900+ }
901+
872902static number_methods long_as_number = {
873903 long_add , /*nb_add*/
874904 long_sub , /*nb_subtract*/
@@ -880,6 +910,7 @@ static number_methods long_as_number = {
880910 long_neg , /*nb_negative*/
881911 long_pos , /*tp_positive*/
882912 long_abs , /*tp_absolute*/
913+ long_nonzero , /*tp_nonzero*/
883914};
884915
885916typeobject Longtype = {
0 commit comments