[pypy-commit] pypy bigint-with-int-ops: Support Long Int compare ops
stian
noreply at buildbot.pypy.org
Fri Aug 9 00:11:46 CEST 2013
Author: stian
Branch: bigint-with-int-ops
Changeset: r66025:7500e0cc59b1
Date: 2013-08-09 00:10 +0200
http://bitbucket.org/pypy/pypy/changeset/7500e0cc59b1/
Log: Support Long Int compare ops
diff --git a/pypy/objspace/std/longobject.py b/pypy/objspace/std/longobject.py
--- a/pypy/objspace/std/longobject.py
+++ b/pypy/objspace/std/longobject.py
@@ -155,17 +155,17 @@
return space.newbool(w_long1.num.ge(w_long2.num))
def lt__Long_Int(space, w_long1, w_int2):
- return space.newbool(w_long1.num.lt(rbigint.fromint(w_int2.intval)))
+ return space.newbool(w_long1.num.int_lt(w_int2.intval))
def le__Long_Int(space, w_long1, w_int2):
- return space.newbool(w_long1.num.le(rbigint.fromint(w_int2.intval)))
+ return space.newbool(w_long1.num.int_le(w_int2.intval))
def eq__Long_Int(space, w_long1, w_int2):
- return space.newbool(w_long1.num.eq(rbigint.fromint(w_int2.intval)))
+ return space.newbool(w_long1.num.int_eq(w_int2.intval))
def ne__Long_Int(space, w_long1, w_int2):
- return space.newbool(w_long1.num.ne(rbigint.fromint(w_int2.intval)))
+ return space.newbool(w_long1.num.int_ne(w_int2.intval))
def gt__Long_Int(space, w_long1, w_int2):
- return space.newbool(w_long1.num.gt(rbigint.fromint(w_int2.intval)))
+ return space.newbool(w_long1.num.int_gt(w_int2.intval))
def ge__Long_Int(space, w_long1, w_int2):
- return space.newbool(w_long1.num.ge(rbigint.fromint(w_int2.intval)))
+ return space.newbool(w_long1.num.int_ge(w_int2.intval))
def lt__Int_Long(space, w_int1, w_long2):
return space.newbool(rbigint.fromint(w_int1.intval).lt(w_long2.num))
diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py
--- a/rpython/rlib/rbigint.py
+++ b/rpython/rlib/rbigint.py
@@ -499,10 +499,27 @@
i += 1
return True
+ @jit.elidable
+ def int_eq(self, other):
+ """ eq with int """
+
+ if not int_in_valid_range(other):
+ # Fallback to Long.
+ return self.eq(rbigint.fromint(other))
+
+ if self.numdigits() > 1:
+ return False
+
+ return (self.sign * self.digit(0)) == other
+
@jit.look_inside
def ne(self, other):
return not self.eq(other)
+ @jit.look_inside
+ def int_ne(self, other):
+ return not self.int_eq(other)
+
@jit.elidable
def lt(self, other):
if self.sign > other.sign:
@@ -538,18 +555,67 @@
i -= 1
return False
+ @jit.elidable
+ def int_lt(self, other):
+ """ lt where other is an int """
+
+ if not int_in_valid_range(other):
+ # Fallback to Long.
+ return self.lt(rbigint.fromint(other))
+
+ osign = 1
+ if other == 0:
+ osign = 0
+ elif other < 0:
+ osign = -1
+
+ if self.sign > osign:
+ return False
+ elif self.sign < osign:
+ return True
+
+ digits = self.numdigits()
+
+ if digits > 1:
+ if osign == 1:
+ return False
+ else:
+ return True
+
+ d1 = self.sign * self.digit(0)
+ if d1 < other:
+ return True
+ return False
+
@jit.look_inside
def le(self, other):
return not other.lt(self)
@jit.look_inside
+ def int_le(self, other):
+ # Alternative that might be faster, reimplant this. as a check with other + 1. But we got to check for overflow
+ # or reduce valid range.
+
+ if self.int_eq(other):
+ return True
+ return self.int_lt(other)
+
+ @jit.look_inside
def gt(self, other):
return other.lt(self)
@jit.look_inside
+ def int_gt(self, other):
+ return not self.int_le(other)
+
+ @jit.look_inside
def ge(self, other):
return not self.lt(other)
+ @jit.look_inside
+ def int_ge(self, other):
+ return not self.int_lt(other)
+
@jit.elidable
def hash(self):
return _hash(self)
diff --git a/rpython/rlib/test/test_rbigint.py b/rpython/rlib/test/test_rbigint.py
--- a/rpython/rlib/test/test_rbigint.py
+++ b/rpython/rlib/test/test_rbigint.py
@@ -375,6 +375,13 @@
f2 = rbigint.fromlong(y)
assert (x < y) == f1.lt(f2)
+ def test_int_lt(self):
+ val = [0, 0x11111111, 0x11111112]
+ for x in gen_signs(val):
+ for y in gen_signs(val):
+ f1 = rbigint.fromlong(x)
+ assert (x < y) == f1.int_lt(y)
+
def test_order(self):
f6 = rbigint.fromint(6)
f7 = rbigint.fromint(7)
@@ -383,6 +390,14 @@
assert (f6.gt(f6), f6.gt(f7), f7.gt(f6)) == (0,0,1)
assert (f6.ge(f6), f6.ge(f7), f7.ge(f6)) == (1,0,1)
+ def test_int_order(self):
+ f6 = rbigint.fromint(6)
+ f7 = rbigint.fromint(7)
+ assert (f6.int_lt(6), f6.int_lt(7), f7.int_lt(6)) == (0,1,0)
+ assert (f6.int_le(6), f6.int_le(7), f7.int_le(6)) == (1,1,0)
+ assert (f6.int_gt(6), f6.int_gt(7), f7.int_gt(6)) == (0,0,1)
+ assert (f6.int_ge(6), f6.int_ge(7), f7.int_ge(6)) == (1,0,1)
+
def test_int_conversion(self):
f1 = rbigint.fromlong(12332)
f2 = rbigint.fromint(12332)
More information about the pypy-commit
mailing list