From: Guido van Rossum Date: Sun, 16 Mar 1997 00:37:59 +0000 (+0000) Subject: New long_lshift, without restriction on size of shift count, by Tim Peters. X-Git-Tag: v1.5a1~277 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f2e499b1d760076f519b618105c112495d6f7911;p=python New long_lshift, without restriction on size of shift count, by Tim Peters. This makes it possible to write 1L<<1000000, memory permitting. --- diff --git a/Objects/longobject.c b/Objects/longobject.c index 8de5456943..123d570b2b 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -1214,10 +1214,11 @@ long_lshift(a, b) longobject *a; longobject *b; { + /* This version due to Tim Peters */ longobject *z; long shiftby; - int newsize, wordshift, loshift, hishift, i, j; - digit lomask, himask; + int oldsize, newsize, wordshift, remshift, i, j; + twodigits accum; shiftby = getlongvalue((object *)b); if (shiftby == -1L && err_occurred()) @@ -1226,26 +1227,18 @@ long_lshift(a, b) err_setstr(ValueError, "negative shift count"); return NULL; } - if (shiftby > MASK) { + if ((long)(int)shiftby != shiftby) { err_setstr(ValueError, "outrageous left shift count"); return NULL; } - if (shiftby % SHIFT == 0) { - wordshift = shiftby / SHIFT; - loshift = 0; - hishift = SHIFT; - newsize = ABS(a->ob_size) + wordshift; - lomask = MASK; - himask = 0; - } - else { - wordshift = shiftby / SHIFT + 1; - loshift = SHIFT - shiftby%SHIFT; - hishift = shiftby % SHIFT; - newsize = ABS(a->ob_size) + wordshift; - lomask = ((digit)1 << hishift) - 1; - himask = MASK ^ lomask; - } + /* wordshift, remshift = divmod(shiftby, SHIFT) */ + wordshift = (int)shiftby / SHIFT; + remshift = (int)shiftby - wordshift * SHIFT; + + oldsize = ABS(a->ob_size); + newsize = oldsize + wordshift; + if (remshift) + ++newsize; z = alloclongobject(newsize); if (z == NULL) return NULL; @@ -1253,13 +1246,16 @@ long_lshift(a, b) z->ob_size = -(z->ob_size); for (i = 0; i < wordshift; i++) z->ob_digit[i] = 0; - for (i = wordshift, j = 0; i < newsize; i++, j++) { - if (i > 0) - z->ob_digit[i-1] |= - (a->ob_digit[j] << hishift) & himask; - z->ob_digit[i] = - (a->ob_digit[j] >> loshift) & lomask; - } + accum = 0; + for (i = wordshift, j = 0; j < oldsize; i++, j++) { + accum |= a->ob_digit[j] << remshift; + z->ob_digit[i] = (digit)(accum & MASK); + accum >>= SHIFT; + } + if (remshift) + z->ob_digit[newsize-1] = (digit)accum; + else + assert(!accum); return (object *) long_normalize(z); }