Hi there,

I often come across the situation where I have to construct an integer from 
its binary representation and vice versa. So far you do it in SAGE using 
strings. I have attached a preliminary patch which allows the following code 
to work, i.e. I _replaced_ the binary() method (which returned a string) with 
a method that returns a tuple of Python ints.

sage: e = ZZ(10231252).binary(); e
(1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0)
sage: ZZ(e,2)
10231252

I know that this patch has some issues:
* it breaks doctests which rely on strings (fix by replace ZZ.binary() with 
ZZ.str(2))
* it returns a tuple of Python ints should return tuple (?) of GF(2) elements 
but I didn't want to mess with imports yet
* it can be done faster
* you loose the minus sign: ZZ(-1).binary() is (1,), shall it raise an 
exception then?

I am not out for micromanagement but I hesitate to just submit a polished 
patch as the Integers are such a central building block of SAGE. So, does 
anybody actually like the current behavior of ZZ.binary() which returns a 
(signed) string? Any other objections against making the above work? 

Martin

-- 
name: Martin Albrecht
_pgp: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x8EF0DC99
_www: http://www.informatik.uni-bremen.de/~malb
_jab: [EMAIL PROTECTED]


--~--~---------~--~----~------------~-------~--~----~
To post to this group, send email to sage-devel@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/sage-devel
URLs: http://sage.scipy.org/sage/ and http://modular.math.washington.edu/sage/
-~----------~----~----~----~------~----~------~--~---

diff -r 813dee35adb8 sage/rings/integer.pyx
--- a/sage/rings/integer.pyx	Thu Jun 28 12:53:41 2007 +0200
+++ b/sage/rings/integer.pyx	Thu Jun 28 22:53:10 2007 +0200
@@ -265,6 +265,12 @@ cdef class Integer(sage.structure.elemen
                 # then how do we make Pyrex handle the reference counting?
                 set_from_Integer(self, (<object> PyObject_GetAttrString(x, "_integer_"))())
 
+            elif base == 2 and (PY_TYPE_CHECK(x,list) or PY_TYPE_CHECK(x,tuple)):
+                # we are lazy
+                s = "".join([str(e%2) for e in x])
+                if mpz_set_str(self.value, s, 2) != 0:
+                    raise TypeError, "Unable to convert bit list to an Integer."
+
             else:
                 raise TypeError, "unable to coerce element to an integer"
     
@@ -456,19 +462,33 @@ cdef class Integer(sage.structure.elemen
         """
         return self.str(16)
 
+##     def binary(self):
+##         """
+##         Return the binary digits of self as a string.
+
+##         EXAMPLES:
+##             sage: print Integer(15).binary()
+##             1111
+##             sage: print Integer(16).binary()
+##             10000
+##             sage: print Integer(16938402384092843092843098243).binary()
+##             1101101011101100011110001110010010100111010001101010001111111000101000000000101111000010000011
+##         """
+##         return self.str(2)
+
     def binary(self):
         """
-        Return the binary digits of self as a string.
-
-        EXAMPLES:
-            sage: print Integer(15).binary()
-            1111
-            sage: print Integer(16).binary()
-            10000
-            sage: print Integer(16938402384092843092843098243).binary()
-            1101101011101100011110001110010010100111010001101010001111111000101000000000101111000010000011
-        """
-        return self.str(2)
+        Return the binary digits of self as a tuple in big endian
+        ordering.
+        """
+        cdef long i
+        cdef size_t s = mpz_sizeinbase(self.value, 2)
+        l = [0]*s
+        for i from 0<= i < s:
+            if mpz_tstbit(self.value,i):
+                l[s-i-1] = 1
+        return tuple(l)
+                
 
     def set_si(self, signed long int n):
         """

Reply via email to