Python allows easy creation of an integer from a string of a given base via
int(str, base).
I want to perform the inverse: creation of a string from an integer,
i.e. I want some function int2base(num, base)
, such that:
int(int2base(x, b), b) == x
The function name/argument order is unimportant.
For any number x
and base b
that int()
will accept.
This is an easy function to write: in fact it's easier than describing it in this question. However, I feel like I must be missing something.
I know about the functions bin
, oct
, hex
, but I cannot use them for a few reasons:
Those functions are not available on older versions of Python, with which I need compatibility with (2.2)
I want a general solution that can be called the same way for different bases
I want to allow bases other than 2, 8, 16
Another short one (and easier to understand imo):
And with proper exception handling:
If you need compatibility with ancient versions of Python, you can either use gmpy (which does include a fast, completely general int-to-string conversion function, and can be built for such ancient versions -- you may need to try older releases since the recent ones have not been tested for venerable Python and GMP releases, only somewhat recent ones), or, for less speed but more convenience, use Python code -- e.g., most simply:
ref: http://code.activestate.com/recipes/65212/
Please be aware that this may lead to
for very big integers.
Strings aren't the only choice for representing numbers: you can use a list of integers to represent the order of each digit. Those can easily be converted to a string.
None of the answers reject base < 2; and most will run very slowly or crash with stack overflows for very large numbers (such as 56789 ** 43210). To avoid such failures, reduce quickly like this:
Speedwise,
n_to_base
is comparable withstr
for large numbers (about 0.3s on my machine), but if you compare againsthex
you may be surprised (about 0.3ms on my machine, or 1000x faster). The reason is because the large integer is stored in memory in base 256 (bytes). Each byte can simply be converted to a two-character hex string. This alignment only happens for bases that are powers of two, which is why there are special cases for 2,8, and 16 (and base64, ascii, utf16, utf32).Consider the last digit of a decimal string. How does it relate to the sequence of bytes that forms its integer? Let's label the bytes
s[i]
withs[0]
being the least significant (little endian). Then the last digit issum([s[i]*(256**i) % 10 for i in range(n)])
. Well, it happens that 256**i ends with a 6 for i > 0 (6*6=36) so that last digit is(s[0]*5 + sum(s)*6)%10
. From this, you can see that the last digit depends on the sum of all the bytes. This nonlocal property is what makes converting to decimal harder.You could use
baseconv.py
from my project: https://github.com/semente/python-baseconvSample usage:
There is some bultin converters as for example
baseconv.base2
,baseconv.base16
andbaseconv.base64
.