2012-09-06 12 views
6

Po wprowadzeniuDlaczego dziesiętna funkcja Pythona ma domyślnie 54 miejsca?

from decimal import * 
getcontext().prec = 6 
Decimal (1)/Decimal (7) 

uzyskać wartość

Decimal('0.142857') 

Jednak jeśli wejdę Decimal (1.0/7) uzyskać

Decimal('0.142857142857142849212692681248881854116916656494140625') 
+2

Zauważ, że jest dokładna tylko do '0.1428571428571428' pozostałe cyfry nie są poprawne –

Odpowiedz

12

Porcję 1,0/7 oblicza binarną liczbę zmiennoprzecinkową do 17 cyfr precyzja. Dzieje przeddziesiętny konstruktor widzi go:

>>> d = 1.0/7 
>>> type(d) 
<type 'float'> 
>>> d.as_integer_ratio() 
(2573485501354569, 18014398509481984) 

Frakcja binarny, 2573485501354569/18014398509481984 jest tak blisko jak binarnym zmiennoprzecinkowych można uzyskać przy użyciu 53 bitów precyzją. To nie jest dokładnie 1/7, ale jest całkiem blisko.

Konstruktor dziesiętny przekształca ułamek binarny na tyle miejsc, ile potrzeba, aby uzyskać dokładny dziesiętny odpowiednik. Wynik ty widzisz to co masz, jeśli oceniać 2573485501354569/18014398509481984 dokładnie:

>>> from decimal import Decimal, getcontext 
>>> getcontext().prec = 100 
>>> Decimal(2573485501354569)/Decimal(18014398509481984) 
Decimal('0.142857142857142849212692681248881854116916656494140625') 

punkt Uczenie 1: Binary punkt Pływający oblicza ułamki binarnych do 53 bitów precyzją. Wynik jest zaokrąglany, jeśli to konieczne.

punkt Uczenie 2:dziesiętny konstruktor konwertuje binarnych liczb zmiennoprzecinkowych do dziesiętnych bezstratnie (bez zaokrągleń). Powoduje to uzyskanie o wiele więcej cyfr dokładności niż można się spodziewać (patrz 6. pytanie w Decimal FAQ).

punkt uczenia 3: Moduł dziesiętny jest przeznaczony do leczenia wszystkich numerów jako dokładnie. Tylko wyniki obliczeń są zaokrąglane do dokładności kontekstu. Wejście binarne zmiennoprzecinkowe jest konwertowane na wartość dziesiętną dokładnie, a dokładność kontekstu nie jest stosowana, dopóki nie wykonasz obliczeń z liczbą (Zobacz ostatnie pytanie i odpowiedź w FAQ dziesiętnej dla szczegółów).

Podsumowanie: Nie należy przestawiać binarnego przelicznika zmiennoprzecinkowego przed przekazaniem liczb do modułu dziesiętnego. Pozwól mu wykonywać pracę do pożądanej precyzji.

Nadzieja to pomaga :-)

+0

Świetna odpowiedź, dobrze odpowiedziałeś na to pytanie. Usuwam moje, ponieważ wygląda teraz nieszczęśliwie;) +1 – Tadeck

Powiązane problemy