[pypy-svn] r14279 - pypy/dist/pypy/objspace/std
tismer at codespeak.net
tismer at codespeak.net
Tue Jul 5 14:31:20 CEST 2005
Author: tismer
Date: Tue Jul 5 14:31:19 2005
New Revision: 14279
Modified:
pypy/dist/pypy/objspace/std/longobject.py
Log:
getting closer to correct divmod (was divrem by an oversight :-)
Modified: pypy/dist/pypy/objspace/std/longobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/longobject.py (original)
+++ pypy/dist/pypy/objspace/std/longobject.py Tue Jul 5 14:31:19 2005
@@ -258,19 +258,19 @@
return space.newfloat(div)
def floordiv__Long_Long(space, w_long1, w_long2):
- div, rem = _divrem(space, w_long1, w_long2)
+ div, mod = _l_divmod(space, w_long1, w_long2)
return div
def div__Long_Long(space, w_long1, w_long2):
return floordiv__Long_Long(space, w_long1, w_long2)
def mod__Long_Long(space, w_long1, w_long2):
- div, rem = _divrem(space, w_long1, w_long2)
- return rem
+ div, mod = _l_divmod(space, w_long1, w_long2)
+ return mod
def divmod__Long_Long(space, w_long1, w_long2):
- div, rem = _divrem(space, w_long1, w_long2)
- return space.newtuple([div, rem])
+ div, mod = _l_divmod(space, w_long1, w_long2)
+ return space.newtuple([div, mod])
# helper for pow() #YYYYYY: still needs longval if second argument is negative
def _impl_long_long_pow(space, lv, lw, lz=None):
@@ -961,3 +961,27 @@
if neg:
v.sign = -1
return v
+
+def _l_divmod(space, v, w):
+ """
+ The / and % operators are now defined in terms of divmod().
+ The expression a mod b has the value a - b*floor(a/b).
+ The long_divrem function gives the remainder after division of
+ |a| by |b|, with the sign of a. This is also expressed
+ as a - b*trunc(a/b), if trunc truncates towards zero.
+ Some examples:
+ a b a rem b a mod b
+ 13 10 3 3
+ -13 10 -3 7
+ 13 -10 3 -7
+ -13 -10 -3 -3
+ So, to get from rem to mod, we have to add b if a and b
+ have different signs. We then subtract one from the 'div'
+ part of the outcome to keep the invariant intact.
+ """
+ div, mod = _divrem(space, v, w)
+ if mod.sign * w.sign == -1:
+ mod = add__Long_Long(space, mod, w)
+ one = W_LongObject(space, [r_uint(1)], 1)
+ div = sub__Long_Long(space, div, one)
+ return div, mod
More information about the Pypy-commit
mailing list