1
votes

Obtenez la fraction la plus simplifiée

J'écris un programme qui utilise le module Fractions . Je veux obtenir la fraction la plus simplifiée d'un flotteur. Quand je l'essaye avec des nombres comme 0.5 , cela fonctionne correctement:

>>> str(fractions.Fraction(0.1))
'3602879701896397/36028797018963968'
>>> str(fractions.Fraction(0.55))
'2476979795053773/4503599627370496'

Mais quand je l'essaye avec 0.55 ou 0.1 il affiche des fractions avec un numérateur et un dénominateur très élevés, au lieu de 11/20 et 1/10.

>>> import fractions
>>> str(fractions.Fraction(0.5))
'1/2'

Que puis-je faire pour être sûr que le script affichera toujours la fraction la plus simplifiée? Y a-t-il un moyen de le faire avec le module Fractions ou un autre module, ou je dois écrire la fonction moi-même?


7 commentaires

Lorsque vous passez 0.55 , vous passez un flottant, donc c'est déjà une représentation inexacte avant que la Fraction ne reçoive la valeur


Le point crucial est que de simples fractions décimales comme par ex. 0,1 sont souvent des fractions périodiques dans le système dual. Les nombres à virgule flottante utilisés dans l'ordinateur aggravent encore la situation. Lecture recommandée: Guide en virgule flottante .


Si vous passez une chaîne comme Fraction ('0.1') cela fonctionnera.


@khelwood Savez-vous ce qui fait apparaître les nombres géants pour 0.1 ? Existe-t-il une règle déterministe pour cela?


@roganjosh Seulement que le flotteur essaiera de stocker la valeur la plus proche de 0,1 qui correspond à sa représentation binaire.


Ok, donc je vais passer le nombre sous forme de chaîne. Cela résout le problème


Il ne s'agit pas simplement de stackoverflow.com/questions/23344185/… . Cela n'explique pas pourquoi je dois passer le nombre sous forme de chaîne.


4 Réponses :


2
votes

Essayez ceci:

In [77]: str(fractions.Fraction(0.55).limit_denominator())
Out[77]: '11/20'

In [78]: str(fractions.Fraction(0.1).limit_denominator())
Out[78]: '1/10'

Voir les résultats:

fractions.Fraction(0.1).limit_denominator()


0 commentaires

3
votes

Lorsque vous passez 0.55 , vous passez un float, donc c'est déjà une représentation inexacte avant que la Fraction ne reçoive la valeur.

Alternativement, si vous passez une chaîne à la place, vous pouvez obtenir la valeur exacte que vous voulez:

>>> fractions.Fraction('0.55')
Fraction(11, 20)


0 commentaires

0
votes

Essayez avec l'exemple de module decimal de docs :

>>> from fractions import Fraction
>>> from decimal import Decimal
>>> Fraction(Decimal('0.55'))
>>> Fraction(11, 20)
>>> str(Fraction(11, 20))
>>> '11/20'


0 commentaires

0
votes

Passez-le sous forme de chaîne pour obtenir la fraction simplifiée:

>>> fractions.Fraction('0.1')
Fraction(1, 10)
>>> str(fractions.Fraction('0.1'))
'1/10'


0 commentaires