python - poner - ¿Cómo convertir un número decimal en fracción?
poner fracciones en python (4)
Ampliar la excelente respuesta de Martijn Pieters con una opción adicional debido a la imprecisión inherente a los flotadores más complejos. Por ejemplo:
>>> f = 0.8857097
>>> f.as_integer_ratio()
(1994440937439217, 2251799813685248) # mathematically wrong
>>> Fraction(f)
Fraction(1994440937439217, 2251799813685248) # same result but in a class
>>> Fraction(f).limit_denominator()
Fraction(871913, 984423) # still imprecise
El resultado matemático deseado fue 8857097/10000000
que se puede lograr fundiendo una cuerda y luego manipulándola.
Respuesta editada
Encontré una manera mucho más simple de resolver el problema de precisión.
>>> Fraction(str(f))
Fraction(8857097, 10000000)
Casting en cuanto a una cadena también permite instancias decimales precisas
>>> Decimal(f).as_integer_ratio()
(1994440937439217, 2251799813685248)
>>> Decimal(str(f)).as_integer_ratio()
(8857097, 10000000)
Respuesta original
def float_to_ratio(flt):
if int(flt) == flt: # to prevent 3.0 -> 30/10
return int(flt), 1
flt_str = str(flt)
flt_split = flt_str.split(''.'')
numerator = int(''''.join(flt_split))
denominator = 10 ** len(flt_split[1])
return numerator, denominator
Ahora vamos a probarlo:
>>> float_to_ratio(f)
(8857097, 10000000) # mathematically correct
Notaré que este tipo de precisión de fracción no está optimizado y, por lo general, no será necesario, pero para completarlo está aquí. Esta función no simplifica la fracción, pero puede hacer un procesamiento adicional para reducirla:
>>> n = 0.5
>>> float_to_ratio(n)
(5, 10)
>>> Fraction(*float_to_ratio(n))
Fraction(1, 2)
Me preguntaba cómo convertir un decimal en una fracción en su forma más baja en Python.
Por ejemplo:
0.25 -> 1/4
0.5 -> 1/2
1.25 -> 5/4
3 -> 3/1
Si desea imprimir una fracción adecuada , esta pequeña receta debería hacer:
from fractions import Fraction
def dec_to_proper_frac(dec):
sign = "-" if dec < 0 else ""
frac = Fraction(abs(dec))
return (f"{sign}{frac.numerator // frac.denominator} "
f"{frac.numerator % frac.denominator}/{frac.denominator}")
Esto se imprimirá de la siguiente manera:
>>> dec_to_proper_frac(3.75)
>>> "3 3/4"
Tienes dos opciones:
Use
float.as_integer_ratio()
:>>> (0.25).as_integer_ratio() (1, 4)
(a partir de Python 3.6, puede hacer lo mismo con un objeto
decimal.Decimal()
).Usa las
fractions.Fraction()
Tipo defractions.Fraction()
:>>> from fractions import Fraction >>> Fraction(0.25) Fraction(1, 4)
Este último tiene una conversión str()
muy útil:
>>> str(Fraction(0.25))
''1/4''
>>> print Fraction(0.25)
1/4
Debido a que los valores de coma flotante pueden ser imprecisos, puede terminar con fracciones "extrañas"; limite el denominador para ''simplificar'' la fracción un tanto, con Fraction.limit_denominator()
:
>>> Fraction(0.185)
Fraction(3332663724254167, 18014398509481984)
>>> Fraction(0.185).limit_denominator()
Fraction(37, 200)
Si está usando Python 2.6 todavía, entonces Fraction()
aún no soporta pasar en un float
directamente, pero puede combinar las dos técnicas anteriores en:
Fraction(*0.25.as_integer_ratio())
O simplemente puede usar el método de clase Fraction.from_float()
:
Fraction.from_float(0.25)
que esencialmente hace lo mismo, por ejemplo, tomar la tupla de relación de enteros y pasarla como dos argumentos separados.
Y una pequeña demostración con sus valores de muestra:
>>> for f in (0.25, 0.5, 1.25, 3.0):
... print f.as_integer_ratio()
... print repr(Fraction(f)), Fraction(f)
...
(1, 4)
Fraction(1, 4) 1/4
(1, 2)
Fraction(1, 2) 1/2
(5, 4)
Fraction(5, 4) 5/4
(3, 1)
Fraction(3, 1) 3
Tanto el módulo de fractions
como el método float.as_integer_ratio()
son nuevos en Python 2.6.
from fractions import Fraction
print(Fraction(0.25))
print(Fraction(0.5))
print(Fraction(1.25))
print(Fraction(3))
#1/4
#1/2
#5/4
#3