summaryrefslogtreecommitdiffstats
path: root/Objects/intobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/intobject.c')
-rw-r--r--Objects/intobject.c36
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 *