Python permite la creación fácil de un número entero a partir de una cadena de una base dada a través de
int(str, base).
Quiero realizar la inversa: creación de una cadena a partir de un entero , es decir, quiero alguna función int2base(num, base)
, tal que:
int(int2base(x, b), b) == x
El nombre de la función / orden de los argumentos no es importante.
Para cualquier número x
y base b
que int()
acepte.
Esta es una función fácil de escribir: de hecho, es más fácil que describirla en esta pregunta. Sin embargo, siento que me falta algo.
Yo sé acerca de las funciones bin
, oct
, hex
, pero no puedo usarlos por varias razones:
Esas funciones no están disponibles en versiones anteriores de Python, con las cuales necesito compatibilidad con (2.2)
Quiero una solución general que se pueda llamar de la misma manera para diferentes bases
Quiero permitir bases que no sean 2, 8, 16
Respuestas:
Si necesita compatibilidad con versiones antiguas de Python, puede usar gmpy (que incluye una función de conversión de int a cadena rápida y completamente general, y puede crearse para tales versiones antiguas; es posible que deba probar versiones anteriores ya que los recientes no han sido probados para versiones venerables de Python y GMP, solo algunos recientes), o, para menor velocidad pero más conveniencia, use el código Python, por ejemplo, más simplemente:
fuente
gmpy2.digits(x, base)
.digs = string.digits + string.lowercase + string.uppercase
string.digits + string.letters
)x //= base
que se comporta como/=
en Python 2 al soltar el decimal. Esta respuesta debe incluir un descargo de responsabilidad de que es para Python 2.Sorprendentemente, las personas solo daban soluciones que se convertían en bases pequeñas (más pequeñas que la longitud del alfabeto inglés). No hubo ningún intento de dar una solución que convierta a cualquier base arbitraria de 2 a infinito.
Así que aquí hay una solución súper simple:
así que si necesitas convertir un número súper enorme a la base
577
,numberToBase(67854 ** 15 - 102, 577)
, te dará una solución correcta:[4, 473, 131, 96, 431, 285, 524, 486, 28, 23, 16, 82, 292, 538, 149, 25, 41, 483, 100, 517, 131, 28, 0, 435, 197, 264, 455]
,Que luego puede convertir a cualquier base que desee
fuente
int(4545,16)
dio "11c1" yint(4545,60)
dio "1:15:45". Por lo tanto, la función cumplió tres funciones: la conversión a formatos decimal, computarizado y de marca de tiempo.digits
?ref: http://code.activestate.com/recipes/65212/
Tenga en cuenta que esto puede conducir a
para enteros muy grandes.
fuente
len(numerals)
, y (b)num % b
es, por suerte, <len(numerals)
. por ejemplo, aunque lanumerals
cadena tiene solo 36 caracteres de longitud, baseN (60, 40) regresa'1k'
mientras que baseN (79, 40) genera unIndexError
. Ambos deberían generar algún tipo de error. El código debe revisarse para generar un error sinot 2 <= base <= len(numerals)
.b
no excederíalen(numerals)
, bueno, buena suerte para usted.return numerals[0] if num == 0 else baseN(num // b, b, numerals).lstrip(numerals[0]) + numerals[num % b]
es igual de breve.fuente
0
es innecesario. Aquí está la documentación de Python 2: docs.python.org/2/library/string.html#format-string-syntaxhex(100)[2:]
,oct(100)[2:]
ybin(100)[2:]
.Grandes respuestas! Supongo que la respuesta a mi pregunta fue "no". No me faltaba una solución obvia. Aquí está la función que usaré que condensa las buenas ideas expresadas en las respuestas.
fuente
Recursivo
Yo simplificaría la respuesta más votada a:
Con el mismo consejo para
RuntimeError: maximum recursion depth exceeded in cmp
enteros muy grandes y números negativos. (Podrías usarsys.setrecursionlimit(new_limit)
)Iterativo
Para evitar problemas de recursividad :
fuente
return BS[0] if not n
entonces la condición de parada ? Sólo en caso de que desee utilizar dígitos de lujo, como yo :)return BS[n] if n < b else to_base(n // b) + BN[n % b]
Python no tiene una función incorporada para imprimir un número entero en una base arbitraria. Tendrás que escribir el tuyo si quieres.
fuente
Puedes usarlo
baseconv.py
desde mi proyecto: https://github.com/semente/python-baseconvUso de la muestra:
Hay algunos convertidores bultin como por ejemplo
baseconv.base2
,baseconv.base16
ybaseconv.base64
.fuente
>>> numpy.base_repr(10, base=3) '101'
fuente
clac
por problemas de tiempo de carga. La carga previa de numpy más que triplica el tiempo de ejecución de la evaluación de expresión simple en clac: por ejemplo,clac 1+1
pasó de unos 40 ms a 140 ms.numpy.base_repr()
tiene un límite de 36 como base. De lo contrario, lanza unaValueError
http://code.activestate.com/recipes/65212/
Aquí hay otro del mismo enlace.
fuente
Hice un paquete pip para esto.
Te recomiendo que uses mis bases.py https://github.com/kamijoutouma/bases.py que se inspiró en bases.js
consulte https://github.com/kamijoutouma/bases.py#known-basesalphabets para saber qué bases son utilizables
EDITAR: enlace pip https://pypi.python.org/pypi/bases.py/0.2.2
fuente
salida:
fuente
other-base
es lo mismo queother - base
, así que deberías usarother_base
decimal
es cero.fuente
Una solución recursiva para los interesados. Por supuesto, esto no funcionará con valores binarios negativos. Tendría que implementar Complemento de dos.
fuente
explicación
En cualquier base, cada número es igual a
a1+a2*base**2+a3*base**3...
"La misión" es encontrar todas las "a".Por cada
N=1,2,3...
código, se aíslaaN*base**N
mediante "mouduling" mediante b, para lob=base**(N+1)
cual se divide todo a 's más grande que N, y se divide todo el a' s que su serial es más pequeño que N disminuyendo a cada vez que la función llama a la funciónaN*base**N
.Base% (base-1) == 1 para ello base ** p% (base-1) == 1 y para ello q * base ^ p% (base-1) == q con una sola excepción cuando q = base-1 que devuelve 0. Para arreglar eso en caso de que devuelva 0, la función está comprobando si es 0 desde el principio.
ventajas
en esta muestra solo hay una multiplicación (en lugar de división) y algunos mudulueses, lo que lleva relativamente poco tiempo.
fuente
fuente
fuente
Aquí hay un ejemplo de cómo convertir un número de cualquier base a otra base.
fuente
fuente
Otro corto (y más fácil de entender):
Y con el manejo adecuado de excepciones:
fuente
Otra solución, funciona con las bases 2 a 10, necesita modificaciones para bases más altas:
Ejemplo:
fuente
Aquí hay una versión recursiva que maneja enteros firmados y dígitos personalizados.
fuente
Las cadenas no son la única opción para representar números: puede usar una lista de enteros para representar el orden de cada dígito. Esos se pueden convertir fácilmente en una cadena.
Ninguna de las respuestas rechaza base <2; y la mayoría se ejecutará muy lentamente o se bloqueará con desbordamientos de pila para números muy grandes (como 56789 ** 43210). Para evitar tales fallas, reduzca rápidamente así:
Speedwise,
n_to_base
es comparable constr
grandes números (aproximadamente 0.3s en mi máquina), pero si compara conhex
usted puede sorprenderse (aproximadamente 0.3ms en mi máquina, o 1000 veces más rápido). La razón es porque el entero grande se almacena en la memoria en base 256 (bytes). Cada byte se puede convertir simplemente en una cadena hexadecimal de dos caracteres. Esta alineación solo ocurre para bases que son potencias de dos, razón por la cual hay casos especiales para 2,8 y 16 (y base64, ascii, utf16, utf32).Considere el último dígito de una cadena decimal. ¿Cómo se relaciona con la secuencia de bytes que forma su número entero? Vamos a etiquetar los bytes
s[i]
cons[0]
el menos significativo (little endian). Entonces el último dígito essum([s[i]*(256**i) % 10 for i in range(n)])
. Bueno, sucede que 256 ** i termina con un 6 para i> 0 (6 * 6 = 36) de modo que el último dígito es(s[0]*5 + sum(s)*6)%10
. A partir de esto, puede ver que el último dígito depende de la suma de todos los bytes. Esta propiedad no local es lo que hace que la conversión a decimal sea más difícil.fuente
fuente
Bueno, yo personalmente uso esta función, escrita por mí
Así es como puedes usarlo
print(to_base(7, base=2))
Salida:
"111"
print(to_base(23, base=3))
Salida:
"212"
Por favor, siéntase libre de sugerir mejoras en mi código.
fuente
fuente
Esta es una vieja pregunta, pero pensé que compartiría mi opinión al respecto, ya que siento que es algo más simple que otras respuestas (bueno para bases del 2 al 36):
fuente
No he visto ningún convertidor de flotador aquí. Y me perdí la agrupación por siempre tres dígitos.
QUE HACER:
-números en expresión científica
(n.nnnnnn*10**(exp)
- el'10'
esself.baseDigits[1::-1]/self.to_string(len (self.baseDigits))
-from_string-function.
-base 1 -> números romanos?
-repr de complejo con agles
Así que aquí está mi solución:
fuente
salida:
convertir a cualquier base, inversa también es fácil.
fuente
NameError: global name 'n' is not defined
. Sedivmod(x, n)
supone que esdivmod(x, b)
?