2016-07-03 30 views
3

Während der Übung zum Thema Float-Typ zu Fraction-Typ-Konvertierung in Python 3.52, fand ich den Unterschied zwischen den beiden verschiedenen Möglichkeiten der Konvertierung.Float-zu-Fraction-Konvertierung in Python

Die erste Methode ist:

>>> from fractions import Fraction 
>>> x = 1232.23 
>>> f = Fraction(*x.as_integer_ratio()) 
>>> print(f) 
2709702426188841/2199023255552  #Answer 

Die zweite Methode ist:

>>> from fractions import Fraction 
>>> x = 1232.23 
>>> f = Fraction(str(x)) 
>>> print(f) 
123223/100       #Answer 

ich den Grund für diese zwei verschiedene Antworten wissen? Sorry, wenn das eine dumme Frage ist, bin ich neu in der Programmierung und Python.

Edited: Ich habe einen Weg gefunden ungenaue Fraktion durch erste Methode, um ein genauen von limit_denominator Verfahren erhalten zu konvertieren:

>>> from fractions import Fraction 
>>> x = 1232.23 
>>> f = Fraction(*x.as_integer_ratio()) 
>>> f = f.limit_denominator(100)  
>>> print(f) 
123223/100 

Antwort

4

Noch einmal, weil Fließkommazahlen nicht in Basis-10 (dezimal) gespeichert sind, sondern in Basis-2 (binär).

Eine Zahl mit endlicher Länge in base-10 könnte eine sich wiederholende Dezimalzahl in base-2 sein. Und da Floats eine feste Größe haben, wird diese sich wiederholende Dezimalzahl abgeschnitten, was zu Ungenauigkeiten führt.

Wenn Sie as_integer_ratio für eine Zahl verwenden, die eine wiederkehrende Dezimalzahl in base-2 ist, erhalten Sie einen etwas albernen Bruch als Folge der leichten Ungenauigkeiten in der Umwandlung von Base-10 zu Base-2. Wenn Sie diese beiden Zahlen teilen, liegt der Wert sehr nahe bei Ihrer ursprünglichen Zahl.

Zum Beispiel, während 1/10 = 0,1 in der Basis-10 und nicht eine sich wiederholende Dezimalzahl ist, ist es in der Tat eine wiederholte Dezimalstelle in der Basis-2. Genau wie 1/3 = 0,333 ... in Base-10.

>>> (0.1).as_integer_ratio() 
(3602879701896397, 36028797018963968) 

Wenn Python Ausgabe genau war, würden Sie dies auch sehen, wenn Sie nur 0.1 in der Eingabeaufforderung eingeben, um so etwas wie 1,00000 ... 01 als die Ausgabe zu bekommen. Aber Python verbirgt diese Ungenauigkeit von Ihnen im allgemeinen Fall, was zu Verwirrung führt.

+0

Scheint wie eine genauere Antwort. Könnte das der Grund für diese Anamoly sein? '>>> 0.1 + 0.1 + 0.1-0.3' '5.551115123125783e-17' –

+0

@AbdulHaseeb: Das ist nicht wirklich der Grund, der Grund ist, wie ich erklärte, die Zahlen, die ohne wiederholte Dezimalstellen in Basis dargestellt werden können 10 sind anders als diejenigen, die in Base-2 sein können. –

2

Dies ist eigentlich eine ziemlich gute Frage. Der Grund für die unterschiedlichen Ergebnisse ist, dass x nicht wirklich 1232.23 ist, da es keine genaue Float-Darstellung für 1232.23 gibt, also die fraktionale Darstellung der nächsten Gleitkommadarstellung ist 2709702426188841/2199023255552, aber wenn Sie verwenden behandelt es als den genauen Wert 1232.23 und gibt die wahre beste Bruchteildarstellung der Zahl zurück.