Właśnie ponownie przeczytałem Co nowego w Pythonie 3.0 i stwierdza:
Zmieniono strategię zaokrąglania funkcji round () i typ zwracania. Dokładne przypadki w połowie są teraz zaokrąglane do najbliższego parzystego wyniku zamiast od zera. (Na przykład round (2.5) zwraca teraz 2 zamiast 3).
oraz dokumentacja do rundy :
W przypadku typów wbudowanych obsługujących funkcję round () wartości są zaokrąglane do najbliższej wielokrotności 10 do potęgi minus n; jeśli dwie wielokrotności są jednakowo zbliżone, następuje zaokrąglenie w kierunku parzystego wyboru
Tak więc w wersji 2.7.3 :
In [85]: round(2.5)
Out[85]: 3.0
In [86]: round(3.5)
Out[86]: 4.0
jak bym się spodziewał. Jednak teraz w wersji 3.2.3 :
In [32]: round(2.5)
Out[32]: 2
In [33]: round(3.5)
Out[33]: 4
Wydaje się to sprzeczne z intuicją i sprzeczne z tym, co rozumiem o zaokrąglaniu (i potykaniu się o ludzi). Angielski nie jest moim językiem ojczystym, ale dopóki tego nie przeczytałem, wydawało mi się, że wiem, co oznacza zaokrąglenie: - / Jestem pewien, że w momencie wprowadzenia wersji 3 musiała o tym rozmawiać, ale nie mogłem znaleźć dobrego powodu w moje wyszukiwanie.
- Czy ktoś ma wgląd w to, dlaczego zmieniono to na to?
- Czy są jakieś inne popularne języki programowania (np. C, C ++, Java, Perl, ...), które wykonują tego rodzaju (dla mnie niespójne) zaokrąglanie?
Czego tu brakuje?
AKTUALIZACJA: @ Li-aungYip w komentarzu dotyczącym „Zaokrąglanie bankierów” dało mi właściwe wyszukiwane hasło / słowa kluczowe do wyszukania i znalazłem następujące pytanie SO: Dlaczego .NET domyślnie używa zaokrąglania bankierów? , więc będę to uważnie czytał.
źródło
Odpowiedzi:
Sposób Pythona 3.0 jest obecnie uważany za standardową metodę zaokrąglania, chociaż niektóre implementacje językowe nie są jeszcze dostępne w magistrali.
Prosta technika „zawsze zaokrąglaj 0,5 w górę” skutkuje lekkim odchyleniem w kierunku wyższej liczby. W przypadku dużej liczby obliczeń może to być znaczące. Podejście Python 3.0 eliminuje ten problem.
W powszechnym użyciu jest więcej niż jedna metoda zaokrąglania. IEEE 754, międzynarodowy standard matematyki zmiennoprzecinkowej, definiuje pięć różnych metod zaokrąglania (domyślną jest ta używana w Pythonie 3.0). I są inni.
To zachowanie nie jest tak szeroko znane, jak powinno. AppleScript był, o ile dobrze pamiętam, jednym z pierwszych użytkowników tej metody zaokrąglania.
round
Komenda w AppleScript faktycznie daje kilka opcji, ale round-ku-nawet jest domyślnym, jak to jest w standardzie IEEE 754. Widocznie inżynier, który wdrożyłround
polecenie dostał więc dość wszystkich żądań do „sprawiają, że działa jak dowiedziałem się school ”, którą właśnie zaimplementował:round 2.5 rounding as taught in school
jest poprawnym poleceniem AppleScript. :-)źródło
3
do2.5.round
Możesz kontrolować zaokrąglanie uzyskiwane w Py3000 za pomocą modułu Decimal :
źródło
ROUND_HALF_UP
jest taka sama, jak stare zachowanie Pythona 2.X.setcontext()
funkcję.quantize(decimal.Decimal('1')
sięquantize(decimal.Decimal('0.00')
jeśli chcesz zaokrąglenie do najbliższej 100s, takich jak jakość.round(number, ndigits)
tak długo, jakndigits
jest pozytywne, ale irytująco nie można go użyć do zastąpienia czegoś podobnegoround(5, -1)
.Wystarczy dodać tutaj ważną notatkę z dokumentacji:
https://docs.python.org/dev/library/functions.html#round
Więc nie zdziw się, jeśli uzyskasz następujące wyniki w Pythonie 3.2:
źródło
2.675
dokładnie reprezentować : najbliższy komputer może uzyskać2.67499999999999982236431605997495353221893310546875
. To dość blisko, ale nie równa się dokładnie2.675
: jest trochę bliżej2.67
niż do2.68
. Więcround
funkcja robi właściwą rzecz i zaokrągla ją do bliższej dwucyfrowej wartości po punkcie, a mianowicie2.67
. Nie ma to nic wspólnego z Pythonem, a wszystko, co ma związek z binarnymi liczbami zmiennoprzecinkowymi.Ja też ostatnio miałem z tym problemy. W związku z tym opracowałem moduł Pythona 3, który ma 2 funkcje trueround () i trueround_precision (), które rozwiązują ten problem i zapewniają takie samo zaokrąglanie, do jakiego przyzwyczailiśmy się w szkole podstawowej (a nie zaokrąglanie bankierów). Oto moduł. Po prostu zapisz kod i skopiuj go lub zaimportuj. Uwaga: moduł trueround_precision może zmienić zachowanie zaokrąglania w zależności od potrzeb zgodnie z flagami ROUND_CEILING, ROUND_DOWN, ROUND_FLOOR, ROUND_HALF_DOWN, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_UP i ROUND_05UP w module dziesiętnym (więcej informacji w tej dokumentacji). Aby zapoznać się z poniższymi funkcjami, zapoznaj się z dokumentacją lub użyj help (trueround) i help (trueround_precision), jeśli zostaną skopiowane do interpretera w celu dalszej dokumentacji.
Mam nadzieję że to pomoże,
Narnie
źródło
Python 3.x zaokrągla wartości 0,5 do parzystego sąsiada
można jednak zmienić zaokrąglanie dziesiętne „z powrotem” na zawsze zaokrąglanie 0,5 w górę, w razie potrzeby:
źródło
Zachowanie zaokrąglania w Pythonie 2 w Pythonie 3.
Dodanie 1 na 15. miejscu po przecinku. Dokładność do 15 cyfr.
źródło
2.675
jest2.67499999999999982236431605997495353221893310546875
. Dodanie 1e-15 spowoduje przewrócenie wartości 2,675 i poprawne zaokrąglenie. jeśli ułamek jest już powyżej stałej kodu, dodanie 1e-15 nic nie zmieni w zaokrągleniu.Niektóre przypadki:
Do naprawy:
Jeśli chcesz mieć więcej miejsc po przecinku, na przykład 4, dodaj (+ 0,0000001).
Pracuj dla mnie.
źródło
Reprodukcja próbek:
API: https://docs.python.org/3/library/functions.html#round
Stany:
Biorąc pod uwagę ten wgląd, możesz użyć matematyki, aby go rozwiązać
teraz możesz uruchomić ten sam test z my_round zamiast round.
źródło
Najłatwiejszym sposobem zaokrąglenia w Pythonie 3.x, jak uczy szkoła, jest użycie zmiennej pomocniczej:
A to będą wyniki serii od 2,0 do 3,0 (w krokach co 0,1):
źródło
Możesz kontrolować zaokrąglanie za pomocą modułu math.ceil:
źródło
Wypróbuj ten kod:
Rezultatem będzie:
Wyjście możesz sprawdzić tutaj: https://i.stack.imgur.com/QQUkS.png
źródło