diff options
Diffstat (limited to 'Objects/intobject.c')
-rw-r--r-- | Objects/intobject.c | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/Objects/intobject.c b/Objects/intobject.c index 181cb4f..edfface 100644 --- a/Objects/intobject.c +++ b/Objects/intobject.c @@ -375,7 +375,19 @@ int_lshift(v, w) } a = v->ob_ival; b = ((intobject *)w) -> ob_ival; - return newintobject((unsigned long)a << b); + if (b < 0) { + err_setstr(ValueError, "negative shift count"); + return NULL; + } + if (a == 0 || b == 0) { + INCREF(v); + return (object *) v; + } + if (b >= 32) { + return newintobject(0L); + } + a = (unsigned long)a << b; + return newintobject(a); } static object * @@ -390,7 +402,27 @@ int_rshift(v, w) } a = v->ob_ival; b = ((intobject *)w) -> ob_ival; - return newintobject((unsigned long)a >> b); + if (b < 0) { + err_setstr(ValueError, "negative shift count"); + return NULL; + } + if (a == 0 || b == 0) { + INCREF(v); + return (object *) v; + } + if (b >= 32) { + if (a < 0) + a = -1; + else + a = 0; + } + else { + if (a < 0) + a = ~( ~(unsigned long)a >> b ); + else + a = (unsigned long)a >> b; + } + return newintobject(a); } static object * |