Anonymous avatar Anonymous committed 54da717

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)

Comments (0)

Files changed (6)

pypy/objspace/std/complexobject.py

         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)
 
 

pypy/objspace/std/floattype.py

         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):

pypy/objspace/std/inttype.py

             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):

pypy/objspace/std/longobject.py

                              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)

pypy/objspace/std/longtype.py

             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

rpython/rlib/rbigint.py

             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)
         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)
 
     @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:
     @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
         if self.sign == 0:
             return ONENEGATIVERBIGINT
 
-        ret = self.add(ONERBIGINT)
+        ret = self.int_add(1)
         ret.sign = -ret.sign
         return ret
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.