binary representation of an integer

Discussion in 'Python' started by eliben, Jun 24, 2008.

  1. eliben

    eliben Guest

    Hello,

    I'm interested in converting integers to a binary representation,
    string. I.e. a desired function would produce:

    dec2bin(13) => "1101"

    The other way is easily done in Python with the int() function.

    Perl has a very efficient way to do dec2bin, because its pack/unpack
    have a B format for binary representations, so it's done with:

    sub dec2bin {
    my $str = unpack("B32", pack("N", shift));
    $str =~ s/^0+(?=\d)//; # otherwise you'll get leading zeros
    return $str;
    }

    Python's pack/unpack don't have the binary format for some reason, so
    custom solutions have to be developed. One suggested in the ASPN
    cookbook is:
    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/111286
    However, it is very general and thus inefficient.

    What would be the quickest way to do this ? I think that for dec2bin
    conversion, using hex() and then looping with a hex->bin lookup table
    would be probably much faster than the general baseconvert from the
    recipe.

    What do you think?
    eliben, Jun 24, 2008
    #1
    1. Advertising

  2. Le Tuesday 24 June 2008 10:03:58 eliben, vous avez écrit :
    > Hello,
    >
    > I'm interested in converting integers to a binary representation,
    > string. I.e. a desired function would produce:
    >
    > dec2bin(13) => "1101"
    >
    > The other way is easily done in Python with the int() function.
    >
    > Perl has a very efficient way to do dec2bin, because its pack/unpack
    > have a B format for binary representations, so it's done with:
    >
    > sub dec2bin {
    > my $str = unpack("B32", pack("N", shift));
    > $str =~ s/^0+(?=\d)//; # otherwise you'll get leading zeros
    > return $str;
    > }
    >
    > Python's pack/unpack don't have the binary format for some reason,


    Yes, but I think the %b format specifier has been added to p3k but will not in
    python 2.x.

    > so
    > custom solutions have to be developed. One suggested in the ASPN
    > cookbook is:
    > http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/111286
    > However, it is very general and thus inefficient.
    >
    > What would be the quickest way to do this ? I think that for dec2bin
    > conversion, using hex() and then looping with a hex->bin lookup table
    > would be probably much faster than the general baseconvert from the
    > recipe.
    >
    > What do you think?



    Something like that, less typing with octal conversion :)

    >>>[8]: oct2bin =

    {'0':'000', '1':'001', '2':'010', '3':'011', '4':'100', '5':'101', '6':'110', '7':'111'}

    >>>[9]: ''.join(oct2bin[e] for e in "%o"%35).lstrip('0')

    ...[9]: '100011'



    --
    _____________

    Maric Michaud
    _____________

    Aristote - www.aristote.info
    3 place des tapis
    69004 Lyon
    Tel: +33 4 26 88 00 97
    Mobile: +33 6 32 77 00 21
    Maric Michaud, Jun 24, 2008
    #2
    1. Advertising

  3. On Jun 24, 9:03 am, eliben <> wrote:
    > What would be the quickest way to do this ? I think that for dec2bin
    > conversion, using hex() and then looping with a hex->bin lookup table
    > would be probably much faster than the general baseconvert from the
    > recipe.


    I suspect you're right, but it would be easy to find out: just
    code up the hex->bin method and use the timeit module to do some
    timings. Don't forget to strip the trailing 'L' from hex(n) if n
    is a long.

    If you're prepared to wait for Python 2.6, or work with the beta
    version, then the conversion is already there:

    Macintosh-3:trunk dickinsm$ ./python.exe
    Python 2.6b1+ (trunk:64489, Jun 23 2008, 21:10:40)
    [GCC 4.0.1 (Apple Inc. build 5465)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> bin(13)

    '0b1101'

    Interestingly, unlike hex and oct, bin doesn't add a trailing
    'L' for longs:

    >>> bin(13L)

    '0b1101'

    I wonder whether this is a bug...

    Mark
    Mark Dickinson, Jun 24, 2008
    #3
  4. eliben

    Guest

    On Jun 24, 10:38 am, Mark Dickinson <> wrote:
    > On Jun 24, 9:03 am, eliben <> wrote:
    >
    > > What would be the quickest way to do this ? I think that for dec2bin
    > > conversion, using hex() and then looping with a hex->bin lookup table
    > > would be probably much faster than the general baseconvert from the
    > > recipe.

    >
    > I suspect you're right, but it would be easy to find out: just
    > code up the hex->bin method and use the timeit module to do some
    > timings. Don't forget to strip the trailing 'L' from hex(n) if n
    > is a long.
    >
    > If you're prepared to wait for Python 2.6, or work with the beta
    > version, then the conversion is already there:
    >
    > Macintosh-3:trunk dickinsm$ ./python.exe
    > Python 2.6b1+ (trunk:64489, Jun 23 2008, 21:10:40)
    > [GCC 4.0.1 (Apple Inc. build 5465)] on darwin
    > Type "help", "copyright", "credits" or "license" for more information.>>> bin(13)
    >
    > '0b1101'
    >
    > Interestingly, unlike hex and oct, bin doesn't add a trailing
    > 'L' for longs:
    >
    > >>> bin(13L)

    >
    > '0b1101'
    >
    > I wonder whether this is a bug...
    >
    > Mark


    Strange in 2.6, but I know at least in 3.0 that all integers are C
    Long's now, so the L is no longer required.
    , Jun 24, 2008
    #4
  5. eliben

    Guest

    And:

    # return as a string
    def itob_string(integer, count = 8):
    return "".join(str((integer >> i) & 1) for i in range(count - 1,
    -1, -1))

    # return as an iterator (i.e [0, 0, 0, 0, 1, 0, 1, 0])
    def itob_list(integer, count = 8):
    return [(integer >> i) & 1 for i in range(count - 1, -1, -1)]

    # return as a generator
    def itob_generator(integer, count = 8):
    return ((integer >> i) & 1 for i in range(count - 1, -1, -1))
    , Jun 24, 2008
    #5
  6. eliben

    Guest

    , Jun 24, 2008
    #6
  7. eliben

    Terry Reedy Guest

    wrote:
    > On Jun 24, 10:38 am, Mark Dickinson <> wrote:


    >> Interestingly, unlike hex and oct, bin doesn't add a trailing
    >> 'L' for longs:
    >>
    >>>>> bin(13L)

    >> '0b1101'
    >>
    >> I wonder whether this is a bug...



    > Strange in 2.6, but I know at least in 3.0 that all integers are C
    > Long's now, so the L is no longer required.


    In current 2.x, the trailing L is no longer required for long integer
    input; the lexer decides whether to make an int or long. Similarly,
    ints are automatically converted to longs as needed instead of raising
    overflow errors (as once happended). The trailing L on output would
    have been removed already except for backward compatibility. But there
    was no back-compatibility requirement for 0bxxxx strings.

    In 3.0, all integers are class 'int'. The internal representation as
    fixed or extended precision is entirely an internal implementation matter.
    Terry Reedy, Jun 24, 2008
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mark Dufour
    Replies:
    0
    Views:
    305
    Mark Dufour
    Dec 16, 2003
  2. Harry George
    Replies:
    1
    Views:
    348
    Fredrik Lundh
    Dec 16, 2003
  3. Mark Dufour
    Replies:
    5
    Views:
    360
    Bengt Richter
    Dec 18, 2003
  4. Madhusudan Singh
    Replies:
    6
    Views:
    430
    Peter Hansen
    Oct 21, 2005
  5. Madhusudan Singh
    Replies:
    1
    Views:
    419
    Leif K-Brooks
    Oct 19, 2005
Loading...

Share This Page