En este post de programación en Python te mostraré cómo convertir un número decimal en base 10 con parte fraccionaria a cualquier otra base; para el ejemplo te mostraré cómo convertir a la base 2 (binario), base 8 (octal) y base 16 (hexadecimal).
La diferencia con otros posts que te he mostrado es que ahora vamos a soportar números con punto decimal, parte fraccionaria o como le llames, y no solo números enteros.
Por ejemplo, podremos convertir el número decimal 3722.24
a E8A.3D70
en hexadecimal, usando Python.
Explicación del algoritmo
Debemos separar la parte entera y decimal, algo que podemos hacer con modf
en Python. Luego debemos seguir el procedimiento que hacemos manualmente:
En el caso de la parte entera vamos dividiéndola entre la base y usando el residuo para saber cuál digito irá en el resultado.
Para la parte decimal o fraccionaria, vamos a ir multiplicando el valor decimal por la base, usar la parte entera del resultado como dígito para el resultado, y asignando la parte decimal a la parte fraccionaria original.
Todo esto que te explico está mejor explicado en el post del mismo tema pero en lenguaje C; te invito a darle un vistazo.
Código de la función
He encerrado el comportamiento de la conversión en una función de Python. Esto nos va a servir para convertir cualquier decimal con punto decimal a binario, octal y hexadecimal.
Ya te lo dije varias veces pero te lo repito: gracias a esto podremos convertir también la parte fraccionaria. Aquí el código:
import math
"""
Convertir el decimal con parte fraccionaria a cualquier base
decimal: el número decimal que se desea convertir. Por ejemplo, 12.34
base: la base a la que se desea convertir, si es binario es 2, octal 8, hexadecimal 16
digitos: los dígitos que componen a la base. Si es binario es "01", si es octal es "01234567", etcétera
https://parzibyte.me/blog/
"""
def decimal_a_cualquier_base(decimal, base, digitos):
parte_fraccionaria, parte_entera = math.modf(decimal)
parte_entera = int(parte_entera)
cadena_parte_entera = ""
cadena_parte_fraccionaria = ""
while parte_entera > 0:
residuo = parte_entera % base
digito = digitos[int(residuo)]
cadena_parte_entera += digito
parte_entera = int(parte_entera/base)
# Invertir cadena de parte entera
# [https://parzibyte.me/blog/posts/invertir-cadena-python/](https://parzibyte.me/blog/posts/invertir-cadena-python/)
cadena_parte_entera = cadena_parte_entera[::-1]
sobrante = None
# Un do while
# [https://parzibyte.me/blog/posts/do-while-python/](https://parzibyte.me/blog/posts/do-while-python/)
while True:
resultado = parte_fraccionaria*base
parte_fraccionaria, sobrante = math.modf(resultado)
digito = digitos[int(sobrante)]
cadena_parte_fraccionaria += digito
if sobrante == 0:
break
return cadena_parte_entera + "." + cadena_parte_fraccionaria
Los comentarios explican el funcionamiento del método, pero básicamente recibe el número decimal que vamos a convertir, la base a la que vamos a convertir (por ejemplo, 2 para binario, 16 para hexadecimal, etcétera) y los dígitos que componen a la base.
Modo de uso
Ahora te mostraré cómo usarla. Voy a convertir el mismo número a las 3 bases más usadas, aunque teóricamente se podría convertir a cualquier base.
decimal = 3722.24
en_binario = decimal_a_cualquier_base(decimal, 2, "01")
en_octal = decimal_a_cualquier_base(decimal, 8, "01234567")
en_hexadecimal = decimal_a_cualquier_base(decimal, 16, "0123456789ABCDEF")
print(f"El decimal {decimal} es {en_binario} en binario, {en_octal} en octal y {en_hexadecimal} en hexadecimal")
Poniendo todo junto

El código completo queda así, siéntete libre de modificarlo o mejorarlo. Recuerda que los datos de entrada pueden venir de cualquier lugar, aquí los estoy definiendo dentro del código por simplicidad.
import math
"""
Convertir el decimal con parte fraccionaria a cualquier base
decimal: el número decimal que se desea convertir. Por ejemplo, 12.34
base: la base a la que se desea convertir, si es binario es 2, octal 8, hexadecimal 16
digitos: los dígitos que componen a la base. Si es binario es "01", si es octal es "01234567", etcétera
https://parzibyte.me/blog/
"""
def decimal_a_cualquier_base(decimal, base, digitos):
parte_fraccionaria, parte_entera = math.modf(decimal)
parte_entera = int(parte_entera)
cadena_parte_entera = ""
cadena_parte_fraccionaria = ""
while parte_entera > 0:
residuo = parte_entera % base
digito = digitos[int(residuo)]
cadena_parte_entera += digito
parte_entera = int(parte_entera/base)
# Invertir cadena de parte entera
# [https://parzibyte.me/blog/posts/invertir-cadena-python/](https://parzibyte.me/blog/posts/invertir-cadena-python/)
cadena_parte_entera = cadena_parte_entera[::-1]
sobrante = None
# Un do while
# [https://parzibyte.me/blog/posts/do-while-python/](https://parzibyte.me/blog/posts/do-while-python/)
while True:
resultado = parte_fraccionaria*base
parte_fraccionaria, sobrante = math.modf(resultado)
digito = digitos[int(sobrante)]
cadena_parte_fraccionaria += digito
if sobrante == 0:
break
return cadena_parte_entera + "." + cadena_parte_fraccionaria
decimal = 3722.24
en_binario = decimal_a_cualquier_base(decimal, 2, "01")
en_octal = decimal_a_cualquier_base(decimal, 8, "01234567")
en_hexadecimal = decimal_a_cualquier_base(decimal, 16, "0123456789ABCDEF")
print(f"El decimal {decimal} es {en_binario} en binario, {en_octal} en octal y {en_hexadecimal} en hexadecimal")
Si quieres puedes leer más sobre Python en mi blog.