mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
New long_lshift, without restriction on size of shift count, by Tim Peters.
This makes it possible to write 1L<<1000000, memory permitting.
This commit is contained in:
parent
e053c67780
commit
f2e499b1d7
1 changed files with 21 additions and 25 deletions
|
@ -1214,10 +1214,11 @@ long_lshift(a, b)
|
||||||
longobject *a;
|
longobject *a;
|
||||||
longobject *b;
|
longobject *b;
|
||||||
{
|
{
|
||||||
|
/* This version due to Tim Peters */
|
||||||
longobject *z;
|
longobject *z;
|
||||||
long shiftby;
|
long shiftby;
|
||||||
int newsize, wordshift, loshift, hishift, i, j;
|
int oldsize, newsize, wordshift, remshift, i, j;
|
||||||
digit lomask, himask;
|
twodigits accum;
|
||||||
|
|
||||||
shiftby = getlongvalue((object *)b);
|
shiftby = getlongvalue((object *)b);
|
||||||
if (shiftby == -1L && err_occurred())
|
if (shiftby == -1L && err_occurred())
|
||||||
|
@ -1226,26 +1227,18 @@ long_lshift(a, b)
|
||||||
err_setstr(ValueError, "negative shift count");
|
err_setstr(ValueError, "negative shift count");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (shiftby > MASK) {
|
if ((long)(int)shiftby != shiftby) {
|
||||||
err_setstr(ValueError, "outrageous left shift count");
|
err_setstr(ValueError, "outrageous left shift count");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (shiftby % SHIFT == 0) {
|
/* wordshift, remshift = divmod(shiftby, SHIFT) */
|
||||||
wordshift = shiftby / SHIFT;
|
wordshift = (int)shiftby / SHIFT;
|
||||||
loshift = 0;
|
remshift = (int)shiftby - wordshift * SHIFT;
|
||||||
hishift = SHIFT;
|
|
||||||
newsize = ABS(a->ob_size) + wordshift;
|
oldsize = ABS(a->ob_size);
|
||||||
lomask = MASK;
|
newsize = oldsize + wordshift;
|
||||||
himask = 0;
|
if (remshift)
|
||||||
}
|
++newsize;
|
||||||
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;
|
|
||||||
}
|
|
||||||
z = alloclongobject(newsize);
|
z = alloclongobject(newsize);
|
||||||
if (z == NULL)
|
if (z == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1253,13 +1246,16 @@ long_lshift(a, b)
|
||||||
z->ob_size = -(z->ob_size);
|
z->ob_size = -(z->ob_size);
|
||||||
for (i = 0; i < wordshift; i++)
|
for (i = 0; i < wordshift; i++)
|
||||||
z->ob_digit[i] = 0;
|
z->ob_digit[i] = 0;
|
||||||
for (i = wordshift, j = 0; i < newsize; i++, j++) {
|
accum = 0;
|
||||||
if (i > 0)
|
for (i = wordshift, j = 0; j < oldsize; i++, j++) {
|
||||||
z->ob_digit[i-1] |=
|
accum |= a->ob_digit[j] << remshift;
|
||||||
(a->ob_digit[j] << hishift) & himask;
|
z->ob_digit[i] = (digit)(accum & MASK);
|
||||||
z->ob_digit[i] =
|
accum >>= SHIFT;
|
||||||
(a->ob_digit[j] >> loshift) & lomask;
|
|
||||||
}
|
}
|
||||||
|
if (remshift)
|
||||||
|
z->ob_digit[newsize-1] = (digit)accum;
|
||||||
|
else
|
||||||
|
assert(!accum);
|
||||||
return (object *) long_normalize(z);
|
return (object *) long_normalize(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue