[pypy-commit] pypy bigint-with-int: Use the int_ops some other places, implant a int_truediv placeholder and add ZeroDivisionError
stian
noreply at buildbot.pypy.org
Sat Aug 3 22:37:14 CEST 2013
Author: stian
Branch: bigint-with-int
Changeset: r65942:54da7171d2a4
Date: 2013-08-03 22:36 +0200
http://bitbucket.org/pypy/pypy/changeset/54da7171d2a4/
Log: Use the int_ops some other places, implant a int_truediv placeholder
and add ZeroDivisionError
TODO:
- Fix: 5 .__rsub__(2L) to give NotImplanted
- Fallback to Long transformation if abs(INT) > MASK (currently causes
a few tests to fail with rpython assert errors because we don't do
this)
diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py
--- a/pypy/objspace/std/complexobject.py
+++ b/pypy/objspace/std/complexobject.py
@@ -42,7 +42,7 @@
imag = space.float_w(space.getattr(self, space.wrap("imag")))
real_b = rbigint.fromrarith_int(float2longlong(real))
imag_b = rbigint.fromrarith_int(r_ulonglong(float2longlong(imag)))
- val = real_b.lshift(64).or_(imag_b).lshift(3).or_(rbigint.fromint(tag))
+ val = real_b.lshift(64).or_(imag_b).lshift(3).int_or_(tag)
return space.newlong_from_rbigint(val)
diff --git a/pypy/objspace/std/floattype.py b/pypy/objspace/std/floattype.py
--- a/pypy/objspace/std/floattype.py
+++ b/pypy/objspace/std/floattype.py
@@ -291,7 +291,7 @@
from pypy.objspace.std.model import IDTAG_FLOAT as tag
val = float2longlong(space.float_w(self))
b = rbigint.fromrarith_int(val)
- b = b.lshift(3).or_(rbigint.fromint(tag))
+ b = b.lshift(3).int_or_(tag)
return space.newlong_from_rbigint(b)
def int(self, space):
diff --git a/pypy/objspace/std/inttype.py b/pypy/objspace/std/inttype.py
--- a/pypy/objspace/std/inttype.py
+++ b/pypy/objspace/std/inttype.py
@@ -195,7 +195,7 @@
return None
from pypy.objspace.std.model import IDTAG_INT as tag
b = space.bigint_w(self)
- b = b.lshift(3).or_(rbigint.fromint(tag))
+ b = b.lshift(3).int_or_(tag)
return space.newlong_from_rbigint(b)
def int(self, space):
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
@@ -218,6 +218,17 @@
space.wrap("long/long too large for a float"))
return space.newfloat(f)
+def truediv__Long_Int(space, w_long1, w_int2):
+ try:
+ f = w_long1.num.int_truediv(w_int2.intval)
+ except ZeroDivisionError:
+ raise OperationError(space.w_ZeroDivisionError,
+ space.wrap("long division or modulo by zero"))
+ except OverflowError:
+ raise OperationError(space.w_OverflowError,
+ space.wrap("long/long too large for a float"))
+ return space.newfloat(f)
+
def floordiv__Long_Long(space, w_long1, w_long2):
try:
z = w_long1.num.floordiv(w_long2.num)
diff --git a/pypy/objspace/std/longtype.py b/pypy/objspace/std/longtype.py
--- a/pypy/objspace/std/longtype.py
+++ b/pypy/objspace/std/longtype.py
@@ -130,7 +130,7 @@
return None
from pypy.objspace.std.model import IDTAG_LONG as tag
b = space.bigint_w(self)
- b = b.lshift(3).or_(rbigint.fromint(tag))
+ b = b.lshift(3).int_or_(tag)
return space.newlong_from_rbigint(b)
def unwrap(w_self, space): #YYYYYY
diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py
--- a/rpython/rlib/rbigint.py
+++ b/rpython/rlib/rbigint.py
@@ -711,7 +711,7 @@
elif self._digits[0] == ONEDIGIT:
return rbigint.fromint(self.sign * b)
- res = self.widedigit(0) * b
+ res = self.widedigit(0) * abs(b)
carry = res >> SHIFT
if carry:
return rbigint([_store_digit(res & MASK), _store_digit(carry)], self.sign * (-1 if b < 0 else 1), 2)
@@ -730,6 +730,12 @@
return div
@jit.elidable
+ def int_truediv(self, other):
+ # XXX: Not specialized. Just use regular truediv for now.
+ div = _bigint_true_divide(self, rbigint.fromint(other))
+ return div
+
+ @jit.elidable
def floordiv(self, other):
if self.sign == 1 and other.numdigits() == 1 and other.sign == 1:
digit = other.digit(0)
@@ -748,6 +754,10 @@
@jit.elidable
def int_floordiv(self, other):
+
+ if other == 0:
+ raise ZeroDivisionError("long division or modulo by zero")
+
digit = abs(other)
if self.sign == 1 and other > 0:
if digit == 1:
@@ -878,22 +888,22 @@
@jit.elidable
def int_divmod(v, w):
""" Divmod with int """
- if v.sign != (-1 if w < 0 else 1):
- # TODO, fix.
+
+ if w == 0:
+ raise ZeroDivisionError("long division or modulo by zero")
+
+ wsign = (-1 if w < 0 else 1)
+ if v.sign != wsign:
+ # Divrem1 doesn't deal with the sign difference. Instead of having yet another copy,
+ # Just fallback.
return v.divmod(rbigint.fromint(w))
+
div, mod = _divrem1(v, abs(w))
- if v.sign != (-1 if w < 0 else 1):
- mod = rbigint.fromint(mod)
- mod.sign = -1 if w < 0 else 1
- mod = mod.int_add(w)
-
- if div.sign == 0:
- return ONENEGATIVERBIGINT, mod
- div = div.int_add(1)
- else:
- mod = rbigint.fromint(mod)
- mod.sign = -1 if w < 0 else 1
- div.sign = v.sign * (-1 if w < 0 else 1)
+ mod = rbigint.fromint(mod)
+
+ mod.sign = wsign
+ div.sign = v.sign * wsign
+
return div, mod
@jit.elidable
@@ -1045,7 +1055,7 @@
if self.sign == 0:
return ONENEGATIVERBIGINT
- ret = self.add(ONERBIGINT)
+ ret = self.int_add(1)
ret.sign = -ret.sign
return ret
More information about the pypy-commit
mailing list