Próbuję uzyskać stosunek zmiennej i uzyskać nieoczekiwany wynik. Czy ktoś może to wyjaśnić?

>>> value = 3.2
>>> ratios = value.as_integer_ratio()
>>> ratios
(3602879701896397, 1125899906842624)
>>> ratios[0] / ratios[1]
3.2

Używam Pythona 3.3

Ale myślę, że (16, 5) jest znacznie lepszym rozwiązaniem

I dlaczego poprawia 2.5

>>> value = 2.5
>>> value.as_integer_ratio()
(5, 2)
7
itdxer 21 listopad 2013, 19:04

2 odpowiedzi

Najlepsza odpowiedź

Użyj modułu fractions, aby uprościć frakcje:

>>> from fractions import Fraction
>>> Fraction(3.2)
Fraction(3602879701896397, 1125899906842624)
>>> Fraction(3.2).limit_denominator()
Fraction(16, 5)

Z Fraction.limit_denominator() Funkcja:

Znajduje i zwraca najbliższy Fraction do self, który ma mianownika w większości max_denominator. Ta metoda jest przydatna do znalezienia racjonalnych przybliżeń do danego numeru punktu zmiennego

Numery zmiennoprzecinkowe są ograniczone w precyzji i nie mogą reprezentować wielu liczb dokładnie ; To, co widzisz, jest zaokrągloną reprezentacją, ale prawdziwą liczbą jest:

>>> format(3.2, '.50f')
'3.20000000000000017763568394002504646778106689453125'

Ponieważ liczba zmiennoprzecinkowa jest reprezentowana jako suma frakcji binarnych; 1/5 może być reprezentowany tylko przez dodanie 1/8 + 1/16 + 1/128 + więcej frakcji binarnych do zwiększenia wykładników dwóch.

15
Martijn Pieters 21 listopad 2013, 15:21

To nie jest 16/5, ponieważ 3.2 nie jest 3.2 dokładnie ... jest to trudny punkt przybliżony ... np.: 3.20000000000000017764

5
Jon Clements 21 listopad 2013, 15:07