[pypy-svn] r78236 - in pypy/branch/fast-forward/pypy: objspace/std objspace/std/test rlib rlib/test

afa at codespeak.net afa at codespeak.net
Sat Oct 23 22:15:54 CEST 2010


Author: afa
Date: Sat Oct 23 22:15:50 2010
New Revision: 78236

Modified:
   pypy/branch/fast-forward/pypy/objspace/std/longtype.py
   pypy/branch/fast-forward/pypy/objspace/std/test/test_longobject.py
   pypy/branch/fast-forward/pypy/rlib/rbigint.py
   pypy/branch/fast-forward/pypy/rlib/test/test_rbigint.py
Log:
Add long.bit_length()


Modified: pypy/branch/fast-forward/pypy/objspace/std/longtype.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/longtype.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/std/longtype.py	Sat Oct 23 22:15:50 2010
@@ -91,6 +91,13 @@
 def descr_get_imag(space, w_obj):
     return space.newlong(0)
 
+def bit_length(space, w_obj):
+    try:
+        return space.wrap(w_obj.num.bit_length())
+    except OverflowError:
+        raise OperationError(space.w_OverflowError,
+                             space.wrap("too many digits in integer"))
+
 # ____________________________________________________________
 
 long_typedef = StdTypeDef("long",
@@ -106,5 +113,6 @@
     denominator = typedef.GetSetProperty(descr_get_denominator),
     real = typedef.GetSetProperty(descr_get_real),
     imag = typedef.GetSetProperty(descr_get_imag),
+    bit_length = gateway.interp2app(bit_length),
 )
 long_typedef.registermethods(globals())

Modified: pypy/branch/fast-forward/pypy/objspace/std/test/test_longobject.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/test/test_longobject.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/std/test/test_longobject.py	Sat Oct 23 22:15:50 2010
@@ -269,3 +269,7 @@
             pass
         
         assert type(L(7).conjugate()) is long
+
+    def test_bit_length(self):
+        assert 8L.bit_length() == 4
+        assert (-1<<40).bit_length() == 41

Modified: pypy/branch/fast-forward/pypy/rlib/rbigint.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rlib/rbigint.py	(original)
+++ pypy/branch/fast-forward/pypy/rlib/rbigint.py	Sat Oct 23 22:15:50 2010
@@ -558,6 +558,23 @@
         if self._numdigits() == 1 and self.digits[0] == 0:
             self.sign = 0
 
+    def bit_length(self):
+        i = self._numdigits()
+        if i == 1 and self.digits[0] == 0:
+            return 0
+        msd = self.digits[i - 1]
+        msd_bits = 0
+        if msd >= 32:
+            msd_bits += 6
+            msd >>= 6
+        msd_bits += [
+            0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+            ][msd]
+        # yes, this can overflow: a huge number which fits 3 gigabytes of
+        # memory has around 24 gigabits!
+        bits = ovfcheck((i-1) * SHIFT + msd_bits)
+        return bits
 
     def __repr__(self):
         return "<rbigint digits=%s, sign=%s, %s>" % (self.digits, self.sign, self.str())

Modified: pypy/branch/fast-forward/pypy/rlib/test/test_rbigint.py
==============================================================================
--- pypy/branch/fast-forward/pypy/rlib/test/test_rbigint.py	(original)
+++ pypy/branch/fast-forward/pypy/rlib/test/test_rbigint.py	Sat Oct 23 22:15:50 2010
@@ -325,6 +325,16 @@
         b = rbigint.fromlong(-1<<3000)
         assert a.mul(b).tolong() == (-1<<10000)*(-1<<3000)
 
+    def test_bit_length(self):
+        assert rbigint.fromlong(0).bit_length() == 0
+        assert rbigint.fromlong(1).bit_length() == 1
+        assert rbigint.fromlong(2).bit_length() == 2
+        assert rbigint.fromlong(3).bit_length() == 2
+        assert rbigint.fromlong(4).bit_length() == 3
+        assert rbigint.fromlong(-3).bit_length() == 2
+        assert rbigint.fromlong(-4).bit_length() == 3
+        assert rbigint.fromlong(1<<40).bit_length() == 41
+
 class TestInternalFunctions(object):
     def test__inplace_divrem1(self):
         # signs are not handled in the helpers!



More information about the Pypy-commit mailing list