By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,492 Members | 1,289 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,492 IT Pros & Developers. It's quick & easy.

Base conversion method or module

P: n/a
Is there a Python module or method that can convert between numeric bases? Specifically, I need to
convert between Hex, Decimal and Binary such as 5Ah = 90d = 01011010b.

I searched many places but couldn't find a Python specific one.

Thanks, Jeff
Jul 18 '05 #1
Share this Question
Share on Google+
16 Replies


P: n/a

Jeff Wagner wrote in message <0b********************************@4ax.com>...
Is there a Python module or method that can convert between numeric bases? Specifically, I need toconvert between Hex, Decimal and Binary such as 5Ah = 90d = 01011010b.

I searched many places but couldn't find a Python specific one.

Thanks, Jeff


There was a Python cookbook recipe that did these kinds of conversions,
IIRC. Look around at http://aspn.activestate.com/ASPN/Cookbook/Python.
Numeric might do this sort of thing, too, but I don't know.

Python itself can get you pretty far; the problem is that it's a bit spotty
in making conversions communicable.

For example, int() and long() both accept a string with a base argument, so
you can convert just about any base (2 <= base <= 36) to a Python int or
long.

Python can also go the other way around, taking a number and converting to a
string representation of the bases you want. The problem? There's only a
function to do this for hex and oct, not for bin or any of the other bases
int can handle.

Ideally, there's be a do-it-all function that is the inverse of int(): take
a number and spit out a string representation in any base (2-36) you want.

But the binary case is pretty simple:

def bin(number):
"""bin(number) -> string

Return the binary representation of an integer or long integer.

"""
if number == 0: return '0b0'
binrep = []
while number >0:
binrep.append(number&1)
number >>= 1
binrep.reverse()
return '0b'+''.join(map(str,binrep))
Dealing with negative ints is an exercise for the reader....

Remember also that Python has hex and octal literals.
--
Francis Avila

Jul 18 '05 #2

P: n/a
On Sun, 7 Dec 2003 15:45:41 -0500, "Francis Avila" <fr***********@yahoo.com> wrotf:

Jeff Wagner wrote in message <0b********************************@4ax.com>...
Is there a Python module or method that can convert between numeric bases?

Specifically, I need to
convert between Hex, Decimal and Binary such as 5Ah = 90d = 01011010b.

I searched many places but couldn't find a Python specific one.

Thanks, Jeff


There was a Python cookbook recipe that did these kinds of conversions,
IIRC. Look around at http://aspn.activestate.com/ASPN/Cookbook/Python.
Numeric might do this sort of thing, too, but I don't know.

Python itself can get you pretty far; the problem is that it's a bit spotty
in making conversions communicable.

For example, int() and long() both accept a string with a base argument, so
you can convert just about any base (2 <= base <= 36) to a Python int or
long.

Python can also go the other way around, taking a number and converting to a
string representation of the bases you want. The problem? There's only a
function to do this for hex and oct, not for bin or any of the other bases
int can handle.

Ideally, there's be a do-it-all function that is the inverse of int(): take
a number and spit out a string representation in any base (2-36) you want.

But the binary case is pretty simple:

def bin(number):
"""bin(number) -> string

Return the binary representation of an integer or long integer.

"""
if number == 0: return '0b0'
binrep = []
while number >0:
binrep.append(number&1)
number >>= 1
binrep.reverse()
return '0b'+''.join(map(str,binrep))
Dealing with negative ints is an exercise for the reader....

Remember also that Python has hex and octal literals.


Francis,

I found the Python cookbook recipe you were referring to. It is as follows:

The module name is BaseConvert.py .......

#!/usr/bin/env python

BASE2 = "01"
BASE10 = "0123456789"
BASE16 = "0123456789ABCDEF"
BASE62 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklm nopqrstuvwxyz"

def convert(number,fromdigits,todigits):

if str(number)[0]=='-':
number = str(number)[1:]
neg=1
else:
neg=0

# make an integer out of the number
x=long(0)
for digit in str(number):
x = x*len(fromdigits) + fromdigits.index(digit)

# create the result in base 'len(todigits)'
res=""
while x>0:
digit = x % len(todigits)
res = todigits[digit] + res
x /= len(todigits)
if neg:
res = "-"+res

return res

I am getting an error when I import this module and call it.

#!/usr/bin/python

import BaseConvert
print BaseConvert.convert(90,BASE10,BASE2)

Name Error: name 'Base10' is not defined.

This probably has something to do with namespaces which was biting me a while ago. I thought that
since the 'Base' definitions were global to this module (BaseConvert.py) by being defined outside
the function (convert), that when I imported this module, they would be global, too.

From one of my books, it says, "An import statement creates a new namespace that contains all the
attributes of the module. To access an attribute in this namespace, use the name of the module
object as a prefix: import MyModule ... a = MyModule.f( )" which is what I thought I was
doing.

What am I still missing?

Thanks,
Jeff
Jul 18 '05 #3

P: n/a
Jeff Wagner wrote:
I found the Python cookbook recipe you were referring to. It is as follows:
(what's wrong with just posting an URL?)
I am getting an error when I import this module and call it.

#!/usr/bin/python

import BaseConvert
print BaseConvert.convert(90,BASE10,BASE2)

Name Error: name 'Base10' is not defined.

This probably has something to do with namespaces which was biting me
a while ago. I thought that since the 'Base' definitions were global to this
module (BaseConvert.py) by being defined outside the function (convert),
that when I imported this module, they would be global, too.
in Python, "global" means "belonging to a module", not "visible in all
modules in my entire program"
What am I still missing?


change the call to use BaseConvert.BASE10 and BaseConvert.BASE2

to learn more about local and global names, read this:

http://www.python.org/doc/current/ref/naming.html

</F>


Jul 18 '05 #4

P: n/a
On Mon, 8 Dec 2003 00:40:46 +0100, "Fredrik Lundh" <fr*****@pythonware.com> wrotf:
Jeff Wagner wrote:
I found the Python cookbook recipe you were referring to. It is as follows:


(what's wrong with just posting an URL?)


What a great idea ;) ...
http://aspn.activestate.com/ASPN/Coo.../Recipe/111286
I am getting an error when I import this module and call it.

#!/usr/bin/python

import BaseConvert
print BaseConvert.convert(90,BASE10,BASE2)

Name Error: name 'Base10' is not defined.

This probably has something to do with namespaces which was biting me
a while ago. I thought that since the 'Base' definitions were global to this
module (BaseConvert.py) by being defined outside the function (convert),
that when I imported this module, they would be global, too.


in Python, "global" means "belonging to a module", not "visible in all
modules in my entire program"
What am I still missing?


change the call to use BaseConvert.BASE10 and BaseConvert.BASE2

to learn more about local and global names, read this:

http://www.python.org/doc/current/ref/naming.html

</F>

Thanks,
Jeff
Jul 18 '05 #5

P: n/a

"Jeff Wagner" <JW*****@hotmail.com> wrote in message
news:ji********************************@4ax.com...
On Sun, 7 Dec 2003 15:45:41 -0500, "Francis Avila" <fr***********@yahoo.com> wrotf:

I am getting an error when I import this module and call it.

#!/usr/bin/python

import BaseConvert
print BaseConvert.convert(90,BASE10,BASE2)

Name Error: name 'Base10' is not defined.

This probably has something to do with namespaces which was biting me a while ago. I thought that since the 'Base' definitions were global to this module (BaseConvert.py) by being defined outside the function (convert), that when I imported this module, they would be global, too.
From one of my books, it says, "An import statement creates a new namespace that contains all the attributes of the module. To access an attribute in this namespace, use the name of the module object as a prefix: import MyModule ... a = MyModule.f( )" which is what I thought I was doing.

What am I still missing?
print BaseConvert.convert(90, BaseConvert.BASE10, BaseConvert.BASE2)

John Roth
Thanks,
Jeff

Jul 18 '05 #6

P: n/a

Jeff Wagner wrote in message ...
On Mon, 8 Dec 2003 00:40:46 +0100, "Fredrik Lundh" <fr*****@pythonware.com> wrotf:
Jeff Wagner wrote:
I found the Python cookbook recipe you were referring to. It is as
follows:
(what's wrong with just posting an URL?)


What a great idea ;) ...
http://aspn.activestate.com/ASPN/Coo.../Recipe/111286


Hey, I found another one which is the more general "inverse of int/long"
function I was pining for (and thus learning for the n-th time that one
should check the cookbook first before reinventing the wheel):

http://aspn.activestate.com/ASPN/Coo.../Recipe/222109

For some reason it's in the "Text" category, and uses the term "radix,"
which is less common than "base".

Hettinger's version (found in the discussion below) is better.

Shouldn't something like this get into the builtins, so we can get rid of
hex/oct in Python3k?
--
Francis Avila

Jul 18 '05 #7

P: n/a
>Subject: Re: Base conversion method or module
From: "Francis Avila" fr***********@yahoo.com
Date: 12/7/2003 8:52 PM Central Standard Time
Message-id: <vt************@corp.supernews.com>
Jeff Wagner wrote in message ...
On Mon, 8 Dec 2003 00:40:46 +0100, "Fredrik Lundh" <fr*****@pythonware.com>wrotf:
Jeff Wagner wrote:

I found the Python cookbook recipe you were referring to. It is asfollows:
(what's wrong with just posting an URL?)


What a great idea ;) ...
http://aspn.activestate.com/ASPN/Coo.../Recipe/111286


Hey, I found another one which is the more general "inverse of int/long"
function I was pining for (and thus learning for the n-th time that one
should check the cookbook first before reinventing the wheel):

http://aspn.activestate.com/ASPN/Coo.../Recipe/222109


These are nice, but they're very slow:

For i=2**177149 - 1

224.797000051 sec for baseconvert
202.733999968 sec for dec2bin (my routine)
137.735000014 sec for radix

Compare those to the .digits function that is part of GMPY

0.59399998188 sec

That can make quite a difference when you're running through a couple million
iterations.


For some reason it's in the "Text" category, and uses the term "radix,"
which is less common than "base".

Hettinger's version (found in the discussion below) is better.

Shouldn't something like this get into the builtins, so we can get rid of
hex/oct in Python3k?
--
Francis Avila


--
Mensanator
Ace of Clubs
Jul 18 '05 #8

P: n/a
On Sun, 7 Dec 2003 21:52:23 -0500, "Francis Avila" <fr***********@yahoo.com> wrotf:

Jeff Wagner wrote in message ...
On Mon, 8 Dec 2003 00:40:46 +0100, "Fredrik Lundh" <fr*****@pythonware.com>

wrotf:
Jeff Wagner wrote:

I found the Python cookbook recipe you were referring to. It is asfollows:
(what's wrong with just posting an URL?)


What a great idea ;) ...
http://aspn.activestate.com/ASPN/Coo.../Recipe/111286


Hey, I found another one which is the more general "inverse of int/long"
function I was pining for (and thus learning for the n-th time that one
should check the cookbook first before reinventing the wheel):

http://aspn.activestate.com/ASPN/Coo.../Recipe/222109

For some reason it's in the "Text" category, and uses the term "radix,"
which is less common than "base".

Hettinger's version (found in the discussion below) is better.

Shouldn't something like this get into the builtins, so we can get rid of
hex/oct in Python3k?


Thanks Francis, this is excellent! I think I just made a major breakthrough. It's all starting to
come together. I'm sure something will stump me again, though (and it's going to be Classes when I
get there ;)

Jeff
Jul 18 '05 #9

P: n/a
On 08 Dec 2003 04:45:17 GMT, me********@aol.compost (Mensanator) wrotf:
Subject: Re: Base conversion method or module
From: "Francis Avila" fr***********@yahoo.com
Date: 12/7/2003 8:52 PM Central Standard Time
Message-id: <vt************@corp.supernews.com>
Jeff Wagner wrote in message ...
On Mon, 8 Dec 2003 00:40:46 +0100, "Fredrik Lundh" <fr*****@pythonware.com>

wrotf:

Jeff Wagner wrote:

> I found the Python cookbook recipe you were referring to. It is as

follows:

(what's wrong with just posting an URL?)

What a great idea ;) ...
http://aspn.activestate.com/ASPN/Coo.../Recipe/111286


Hey, I found another one which is the more general "inverse of int/long"
function I was pining for (and thus learning for the n-th time that one
should check the cookbook first before reinventing the wheel):

http://aspn.activestate.com/ASPN/Coo.../Recipe/222109


These are nice, but they're very slow:

For i=2**177149 - 1

224.797000051 sec for baseconvert
202.733999968 sec for dec2bin (my routine)
137.735000014 sec for radix

Compare those to the .digits function that is part of GMPY

0.59399998188 sec

That can make quite a difference when you're running through a couple million
iterations.


So I decide to go and try out this GMPY and download the win32 binaries. It consists of two files,
gmpy.pyd and pysymbolicext.pyd ... what do I do with them, just copy them to the lib folder?

Then it says I need GMP-4.x so I get that, too. It's like nothing I've ever seen before. How can I
install that on my WinXP box?

Thanks, Jeff
Jul 18 '05 #10

P: n/a

"Jeff Wagner" <JW*****@hotmail.com> wrote in message
news:0b********************************@4ax.com...
So I decide to go and try out this GMPY and download the win32 binaries. It consists of two files, gmpy.pyd and pysymbolicext.pyd ... what do I do with them, just copy them to the lib folder?

Specifically, Pythonx.y/Libs/site-packages (at least on my system)
import sys; sys.path


should have site-packages dir near beginning.
Then it says I need GMP-4.x so I get that, too. It's like nothing I've ever seen before. How can I install that on my WinXP box?


no idea. sorry. .so is unix version of .dll. try gmp site for windows
..dll binary

tjr
Jul 18 '05 #11

P: n/a
>Subject: Re: Base conversion method or module
From: Jeff Wagner JW*****@hotmail.com
Date: 12/8/2003 1:01 AM Central Standard Time
Message-id: <0b********************************@4ax.com>

On 08 Dec 2003 04:45:17 GMT, me********@aol.compost (Mensanator) wrotf:
Subject: Re: Base conversion method or module
From: "Francis Avila" fr***********@yahoo.com
Date: 12/7/2003 8:52 PM Central Standard Time
Message-id: <vt************@corp.supernews.com>
Jeff Wagner wrote in message ...
On Mon, 8 Dec 2003 00:40:46 +0100, "Fredrik Lundh"<fr*****@pythonware.com>wrotf:

>Jeff Wagner wrote:
>
>> I found the Python cookbook recipe you were referring to. It is as
follows:
>
>(what's wrong with just posting an URL?)

What a great idea ;) ...
http://aspn.activestate.com/ASPN/Coo.../Recipe/111286

Hey, I found another one which is the more general "inverse of int/long"
function I was pining for (and thus learning for the n-th time that one
should check the cookbook first before reinventing the wheel):

http://aspn.activestate.com/ASPN/Coo.../Recipe/222109
These are nice, but they're very slow:

For i=2**177149 - 1

224.797000051 sec for baseconvert
202.733999968 sec for dec2bin (my routine)
137.735000014 sec for radix

Compare those to the .digits function that is part of GMPY

0.59399998188 sec

That can make quite a difference when you're running through a couple

million
iterations.


So I decide to go and try out this GMPY and download the win32 binaries. It
consists of two files,
gmpy.pyd and pysymbolicext.pyd ... what do I do with them, just copy them to
the lib folder?


Yes. Did you get the documentation files also? You'll want gmpydoc.txt as it
lists all the functions. Unfortunately, it's a Unix test file (no carraige
returns) making it useless for Windows Notepad unless you convert the line
feeds to carraige return/line feed.

Then it says I need GMP-4.x so I get that, too. It's like nothing I've ever
seen before. How can I
install that on my WinXP box?
You only need that if you are going to compile from the source files. The
Windows binaries are already compiled, so you shouldn't need to do that step.

Thanks, Jeff


--
Mensanator
Ace of Clubs
Jul 18 '05 #12

P: n/a
On 09 Dec 2003 04:57:18 GMT, me********@aol.compost (Mensanator) wrotf:
So I decide to go and try out this GMPY and download the win32 binaries. It
consists of two files,
gmpy.pyd and pysymbolicext.pyd ... what do I do with them, just copy them to
the lib folder?


Yes. Did you get the documentation files also? You'll want gmpydoc.txt as it
lists all the functions. Unfortunately, it's a Unix test file (no carraige
returns) making it useless for Windows Notepad unless you convert the line
feeds to carraige return/line feed.


Ok, I got it, cleaned it up and read it. It's pretty good.
Then it says I need GMP-4.x so I get that, too. It's like nothing I've ever
seen before. How can I
install that on my WinXP box?


You only need that if you are going to compile from the source files. The
Windows binaries are already compiled, so you shouldn't need to do that step.


Ok, I must have misunderstood. I am trying something that doesn't seem to be working.

If I try to take 01011010 (5A) from binary to hex, here is what I get:
gmpy.digits(01011010,16) #this is not correct. '0x41208'

From binary to decimal doesn't work either. gmpy.digits(01011010,10) '266760'

If I go from decimal to hex, it works. gmpy.digits(90,16) '0x5a'

From decimal to binary seems to work ok. gmpy.digits(90,2) '1011010'

From hex to binary seems to work. gmpy.digits(0x5a,2)

'1011010'

I''m not sure why the binary to x doesn't seem to work.

Jeff
Jul 18 '05 #13

P: n/a
On Tue, Dec 09, 2003 at 06:35:34AM +0000, Jeff Wagner wrote:

Ok, I must have misunderstood. I am trying something that doesn't seem to be working.

If I try to take 01011010 (5A) from binary to hex, here is what I get:
gmpy.digits(01011010,16) #this is not correct. '0x41208'
From binary to decimal doesn't work either.
gmpy.digits(01011010,10)

'266760'


In Python, integer literals beginning with '0' are in octal, just as how
literals beginning with '0x' are in hex, so 01011010 really is 266760:
print 01011010

266760

So it looks like gmpy is functioning correctly.

-Andrew.
Jul 18 '05 #14

P: n/a
On Tue, 9 Dec 2003 17:45:20 +1100, Andrew Bennetts <an***************@puzzling.org> wrotf:
On Tue, Dec 09, 2003 at 06:35:34AM +0000, Jeff Wagner wrote:

Ok, I must have misunderstood. I am trying something that doesn't seem to be working.

If I try to take 01011010 (5A) from binary to hex, here is what I get:
>>> gmpy.digits(01011010,16) #this is not correct.

'0x41208'
>From binary to decimal doesn't work either.
>>> gmpy.digits(01011010,10)

'266760'


In Python, integer literals beginning with '0' are in octal, just as how
literals beginning with '0x' are in hex, so 01011010 really is 266760:
print 01011010266760

So it looks like gmpy is functioning correctly.

-Andrew.


Ok, so I get rid of the leading 0 and here is what I get:
gmpy.digits(1011010,10)

'1011010'

why? How do I tell gmpy that 1011010 is binary and I want it to convert to decimal or hex?

Jeff
Jul 18 '05 #15

P: n/a
On Tue, Dec 09, 2003 at 11:20:43PM +0000, Jeff Wagner wrote:
On Tue, 9 Dec 2003 17:45:20 +1100, Andrew Bennetts <an***************@puzzling.org> wrotf:

In Python, integer literals beginning with '0' are in octal, just as how
literals beginning with '0x' are in hex, so 01011010 really is 266760:
> print 01011010

266760

So it looks like gmpy is functioning correctly.

-Andrew.


Ok, so I get rid of the leading 0 and here is what I get:
gmpy.digits(1011010,10) '1011010'

why? How do I tell gmpy that 1011010 is binary and I want it to convert to decimal or hex?


You seem to be confusing the value of a number with its representation.

Python's 'int' type simply holds a value. It doesn't know the difference
between 90, 0x5A, and int('1011010', 2). They are all the same number, even
though they represented differently in source code.

So, what you *really* are trying to ask is: "How do I take a representation
of a number in binary (i.e. base 2), and convert it to a representation in
decimal or hex?"

The answer is to first convert your representation to a value -- python's
builtin int can convert string representation of numbers with any base from
2 to 36, e.g.:
int('1011010', 2) 90 int('5A', 16)

90

(I wouldn't be surprised if gmpy also could do this, but I don't know gmpy)

Note that I am passing strings to int, not bare literals! If I wrote
"int(1011010, 2)", python would compile 1011010 as a number in base 10, and
pass that number to int instead of the string representation of the number
we really want.

Then you want to pass this value to gmpy.digits, e.g.

num = int('1011010', 2)
print gmpy.digits(num, 16)

-Andrew.
Jul 18 '05 #16

P: n/a
On Wed, 10 Dec 2003 10:44:37 +1100, Andrew Bennetts <an***************@puzzling.org> wrotf:
On Tue, Dec 09, 2003 at 11:20:43PM +0000, Jeff Wagner wrote:
On Tue, 9 Dec 2003 17:45:20 +1100, Andrew Bennetts <an***************@puzzling.org> wrotf:
>
>In Python, integer literals beginning with '0' are in octal, just as how
>literals beginning with '0x' are in hex, so 01011010 really is 266760:
>
>>>> print 01011010
>266760
>
>So it looks like gmpy is functioning correctly.
>
>-Andrew.
>


Ok, so I get rid of the leading 0 and here is what I get:
>>> gmpy.digits(1011010,10)

'1011010'

why? How do I tell gmpy that 1011010 is binary and I want it to convert to decimal or hex?


You seem to be confusing the value of a number with its representation.

Python's 'int' type simply holds a value. It doesn't know the difference
between 90, 0x5A, and int('1011010', 2). They are all the same number, even
though they represented differently in source code.

So, what you *really* are trying to ask is: "How do I take a representation
of a number in binary (i.e. base 2), and convert it to a representation in
decimal or hex?"

The answer is to first convert your representation to a value -- python's
builtin int can convert string representation of numbers with any base from
2 to 36, e.g.:
int('1011010', 2)90 int('5A', 16)

90

(I wouldn't be surprised if gmpy also could do this, but I don't know gmpy)

Note that I am passing strings to int, not bare literals! If I wrote
"int(1011010, 2)", python would compile 1011010 as a number in base 10, and
pass that number to int instead of the string representation of the number
we really want.

Then you want to pass this value to gmpy.digits, e.g.

num = int('1011010', 2)
print gmpy.digits(num, 16)

-Andrew.


Thank you ... wow, so much to learn. You're right, I was confusing the value of a number with its
representation.

Jeff
Jul 18 '05 #17

This discussion thread is closed

Replies have been disabled for this discussion.