[pypy-svn] r45706 - in pypy/branch/pypy-more-rtti-inprogress/rlib: . test
arigo at codespeak.net
arigo at codespeak.net
Thu Aug 16 13:01:40 CEST 2007
Author: arigo
Date: Thu Aug 16 13:01:40 2007
New Revision: 45706
Modified:
pypy/branch/pypy-more-rtti-inprogress/rlib/rbigint.py
pypy/branch/pypy-more-rtti-inprogress/rlib/test/test_rbigint.py
Log:
Added rbigint.tolonglong().
Modified: pypy/branch/pypy-more-rtti-inprogress/rlib/rbigint.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/rlib/rbigint.py (original)
+++ pypy/branch/pypy-more-rtti-inprogress/rlib/rbigint.py Thu Aug 16 13:01:40 2007
@@ -1,4 +1,5 @@
-from pypy.rlib.rarithmetic import LONG_BIT, intmask, r_uint, r_ulonglong, ovfcheck
+from pypy.rlib.rarithmetic import LONG_BIT, intmask, r_uint, r_ulonglong
+from pypy.rlib.rarithmetic import ovfcheck, r_longlong
import math, sys
@@ -174,6 +175,9 @@
def toint(self):
return _AsLong(self)
+ def tolonglong(self):
+ return _AsLongLong(self)
+
def tobool(self):
return self.sign != 0
@@ -194,16 +198,7 @@
def toulonglong(self):
if self.sign == -1:
raise ValueError("cannot convert negative integer to unsigned int")
- x = r_ulonglong(0)
- i = len(self.digits) - 1
- while i >= 0:
- prev = x
- x = (x << SHIFT) + self.digits[i]
- if (x >> SHIFT) != prev:
- raise OverflowError(
- "long int too large to convert to unsigned long long int")
- i -= 1
- return x
+ return _AsULonglong_ignore_sign(self)
def tofloat(self):
return _AsDouble(self)
@@ -1557,6 +1552,39 @@
raise OverflowError
return intmask(x * sign)
+ULONGLONG_BOUND = r_ulonglong(1L << (r_longlong.BITS-1))
+LONGLONG_MIN = r_longlong(-(1L << (r_longlong.BITS-1)))
+
+def _AsLongLong(v):
+ """
+ Get a r_longlong integer from a bigint object.
+ Raises OverflowError if overflow occurs.
+ """
+ x = _AsULonglong_ignore_sign(v)
+ # grr grr grr
+ if x >= ULONGLONG_BOUND:
+ if x == ULONGLONG_BOUND and v.sign < 0:
+ x = LONGLONG_MIN
+ else:
+ raise OverflowError
+ else:
+ x = r_longlong(x)
+ if v.sign < 0:
+ x = -x
+ return x
+
+def _AsULonglong_ignore_sign(v):
+ x = r_ulonglong(0)
+ i = len(v.digits) - 1
+ while i >= 0:
+ prev = x
+ x = (x << SHIFT) + v.digits[i]
+ if (x >> SHIFT) != prev:
+ raise OverflowError(
+ "long int too large to convert to unsigned long long int")
+ i -= 1
+ return x
+
def _hash(v):
# This is designed so that Python ints and longs with the
# same value hash to the same value, otherwise comparisons
Modified: pypy/branch/pypy-more-rtti-inprogress/rlib/test/test_rbigint.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/rlib/test/test_rbigint.py (original)
+++ pypy/branch/pypy-more-rtti-inprogress/rlib/test/test_rbigint.py Thu Aug 16 13:01:40 2007
@@ -3,7 +3,7 @@
from random import random, randint
from pypy.rlib.rbigint import rbigint, SHIFT, MASK
from pypy.rlib import rbigint as lobj
-from pypy.rlib.rarithmetic import r_uint
+from pypy.rlib.rarithmetic import r_uint, r_longlong
import operator, sys
class TestRLong(object):
@@ -408,7 +408,16 @@
ret = lobj._k_lopsided_mul(f1, f2)
assert ret.tolong() == f1.tolong() * f2.tolong()
-
+ def test_longlong(self):
+ max = 1L << (r_longlong.BITS-1)
+ f1 = rbigint.fromlong(max-1) # fits in r_longlong
+ f2 = rbigint.fromlong(-max) # fits in r_longlong
+ f3 = rbigint.fromlong(max) # overflows
+ f4 = rbigint.fromlong(-max-1) # overflows
+ assert f1.tolonglong() == max-1
+ assert f2.tolonglong() == -max
+ py.test.raises(OverflowError, f3.tolonglong)
+ py.test.raises(OverflowError, f4.tolonglong)
class TestTranslatable(object):
More information about the Pypy-commit
mailing list