2016-01-05 28 views
5

Jestem nieco zdezorientowany, jak działa zaokrąglanie w Pythonie.
Czy ktoś mógłby wyjaśnić, dlaczego Python zachowuje się w ten sposób?Jak działa zaokrąglanie w Pythonie?

Przykład:

>>> round(0.05,1) # this makes sense 
0.1 
>>> round(0.15,1) # this doesn't make sense! Why is the result not 0.2? 
0.1 

A sama dla:

>>> round(0.25,1) # this makes sense 
0.3 
>>> round(0.35,1) # in my opinion, should be 0.4 but evaluates to 0.3 
0.3 

Edit: Tak w ogóle, istnieje możliwość, że Python zaokrągla w dół zamiast zaokrąglania. Czy mam rozumieć, że jedyną "nienormalną" rzeczą, która może się zdarzyć, jest to, że Python się kończy? Czy może również zostać "nienormalnie" zaokrąglone ze względu na sposób przechowywania? (Nie znalazłem przypadku, w którym Python zaokrągliłby się, gdy spodziewałem się, że zaokrągli w dół).

+0

pokrewne. 'Print '% .20f% .20f% .20f' % (15, .25, .35) ' –

+0

@Rob_phi: Niezwiązane: twój indeks dolny jest poprawnie wyświetlany nawet na ekranie adresu URL na pasku adresu [po kliknięciu nazwy użytkownika] ... JAK? – gariepy

+0

@gariepy Jeśli skopiujesz adres URL do edytora tekstu, pojawi się on jako: http: // stackoverflow.com/users/8747/rob% E1% B5% A9' - niektóre przeglądarki takie jak Chrome renderują znaki escape z unikodem pasek adresu URL. – Galax

Odpowiedz

12

Jest to zgodne z projektem. Od Pythons' documentation:

Zachowanie round() dla pływaków może być zaskakujące, na przykład: round(2.675, 2) daje 2,67 zamiast oczekiwanego 2,68. To nie jest błąd: wynika to z faktu, że większość ułamków dziesiętnych nie może być przedstawiana dokładnie tak, jak ułamek.

+1

Cóż, to jest do bani. –

+5

Tak, w szczególności "0.15" jest wewnętrznie reprezentowany jako '0.1499999999999999944488848768742172978818416595458984375', a" 0.35 "to' 0.34999999999999997779553950749686919152736663818359375'. Oba rozsądnie zaokrąglają w dół. – Kevin

+0

Generalnie istnieje możliwość, że zostanie zaokrąglona w dół zamiast zaokrąglona w górę. Więc jedyną "nienormalną" rzeczą, która może się stać, jest to, że zostaje zaokrąglona w dół? Czy może również zostać "nienormalnie" zaokrąglone ze względu na sposób przechowywania? (Nie znalazłem przypadku, w którym zostanie ono zaokrąglone, kiedy spodziewam się, że zostanie zaokrąglone w dół.) –

3

Jako przykład, tutaj jest to przypadek, gdzie można uzyskać zaokrąglania:

>>> round(0.0499999999999999999,1) 
0.1 

W tym przypadku 17 „9” s to minimalna ilość, aby spowodować takie zachowanie. Dzieje się tak, ponieważ wewnętrzna reprezentacja 0.0499999999999999999 jest 0.05000000000000000277555756156289135105907917022705078125.

7

To brzmi dla mnie jak trzeba moduł decimal:

from decimal import * 
x = Decimal('0.15') 
print x.quantize(Decimal('0.1'), rounding=ROUND_HALF_UP) 

wyjściowa:

0.2 
+1

@JonasKaufmann: Jeśli potrzebujesz dokładnych reprezentacji dziesiętnych, które brzmią tak, jak Ty, jest to właściwa odpowiedź. Z tego też powodu wynaleziono Cobol. I. Nadal. W. Posługiwać się. :( – gariepy