2

Python has the capability to convert a base 10 integer to base X where 2<=X<=36, with the int() function. It would seem natural (until you've studied group theory) that there would be a way to convert numbers back to base 10, or from base X to base Y for any integer.

I could write a function using from math import log to convert between bases, but I was wondering if there is anything that is already built in to python to accomplish this.

Is there a built in function in Python 3, to perform a change of base between any two bases? What constraints, if any, are there similar to those for int()?

Edit: To clarify, int() only interprets the first argument in base 10. I would like to specify the argument as a different base representation. I am wondering if there is a built in function that takes two arguments for base representation. Example (why int() is not the answer:

>>> int('100',9) == int(str(int('81',9)),10)
False

Edit #2: Say I want to know what 100 is in base 9, I would use the following, int('100', 9) this would return a value of 81. Now say I want to take 81 (in base 9) and turn it back into base 10. Is there a function built into Python to accomplish this, or a way to mark the first argument to indicate that I am giving it a number in base 9?

I know that there is a way to specify this for binary, using 'ob', and hex values using '0x'. For example,

int('0b1100100', 2)

This return a value of 100, what are the prefixes to specify other bases for the first argument.

XisUnknown
  • 125
  • 1
  • 1
  • 10
  • Isn't it the other way round, that `int`converts from any base in [2..36] **to** 10? That would also answer part of your question. – Jeronimo Jun 19 '18 at 05:43
  • 5
    `int()` interprets its first argument in whatever base you tell it to interpret it in. It does not "convert a base 10 integer to base X"; it converts a string in base X to a baseless integer, which happens to be displayed in base 10. I honestly don't understand what you're trying to do with your example code. – jwodder Jun 19 '18 at 16:46
  • @jwodder the example code was to show that int('100',9) is not actually "100 base nine", but only returns a representation of what it would look like. I am beginning to think a simple no would suffice to answer my question, but I will try to edit my question to clarify. Also, I don't know what you mean by a baseless integer. – XisUnknown Jun 21 '18 at 00:53
  • I agree with @squeamishossifrage, this definitely seems a duplicate. I think the issue might be XisUnknown doesn't know how to verbalize the question. – bitsplit Jun 21 '18 at 02:49
  • @squeamishossifrage You're right that I had a hard time verbalizing this. It boils down to the last edit, how do I specify that the first number given in a string is something other than base 10? – XisUnknown Jun 21 '18 at 02:54

1 Answers1

2

When you speak of an integer object, it is not the same as its base N representation.

While internally, the integer is stored in binary, the integer object itself has no base. You can construct an int object from any string of digits in any base N, as long as you specify the base and the string of digits is valid for that base. This is usually restricted to a maximum of 36, since there are 10 decimal digits and 26 letters in the alphabet.

There are special cases for the bases 2, 8, 10, and 16, since they are the most used. For those bases, you can specify the base within the string representation itself. You use prefixes of 0b, 0o, or 0x for 2, 8, and 16 respectively. Decimal is the default and the most used, so it requires no prefix.

If you want to return the base N representation of an integer as a string, i.e. invert the operation int(n, N), you have several options. You can use gmpy.digits(n, N) where n is your int, and N is the base you want. This might be overkill, since it requires installing gmpy.

You can alternatively use something like this:

import string

def int_to_base(n, N):
    """ Return base N representation for int n. """
    base_n_digits = digits + ascii_lowercase + ascii_uppercase
    result = ""
    if n < 0:
        sign = "-"
        n = -n
    else:
        sign = ""
    while n > 0:
        q, r = divmod(n, N)
        result += base_n_digits[r]
        n = q
    if result == "":
        result = "0"
    return sign + "".join(reversed(result))

With that function, or something similar to it, you can return the string base N representation of an integer n in base N, so that:

>>> base_n_string = "81"
>>> base = 9
>>> int_to_base(int("81", 9), 9) == "81"
True
bitsplit
  • 1,040
  • 9
  • 17