Dokumentacja funkcji round () stwierdza, że należy przekazać jej liczbę, a pozycje po przecinku do zaokrąglenia. Dlatego powinien to zrobić:
n = 5.59
round(n, 1) # 5.6
Ale w rzeczywistości wkrada się stara, dobra dziwność zmiennoprzecinkowa i dostajesz:
5.5999999999999996
Na potrzeby interfejsu użytkownika muszę wyświetlić 5.6
. Przeszukałem Internet i znalazłem dokumentację, że jest to zależne od mojej implementacji Pythona. Niestety dzieje się tak zarówno na moim komputerze deweloperskim z systemem Windows, jak i na każdym serwerze Linux, którego próbowałem. Zobacz także tutaj .
Poza utworzeniem własnej okrągłej biblioteki, czy można to obejść?
python
floating-point
rounding
swilliams
źródło
źródło
round(5.55, 1) = 5.5
.Odpowiedzi:
Nie mogę pomóc w sposobie jego przechowywania, ale przynajmniej formatowanie działa poprawnie:
źródło
print '%.2f' % 655.665
ale wraca655.66
, powinno być655.67
from decimal import Decimal, ROUND_HALF_UP, ROUND_HALF_DOWN
# użycie w zaokrąglaniu liczb zmiennoprzecinkowychDecimal(str(655.665)).quantize(Decimal('1.11'), rounding=ROUND_HALF_UP)
# Problemy i ograniczenia w liczbach zmiennoprzecinkowychFormatowanie działa poprawnie, nawet bez konieczności zaokrąglania:
źródło
"{:.1f}".format(n)
'%.5f' % 0.988625
daje0.98862
Jeśli korzystasz z modułu Decimal, możesz przybliżać dane bez użycia funkcji „round”. Oto, czego używałem do zaokrąglania, szczególnie podczas pisania aplikacji pieniężnych:
To zwróci liczbę dziesiętną, która wynosi 16,20.
źródło
rounding='ROUND_UP'
NameError: global name 'ROUND_UP' is not defined
trzeba zaimportować funkcję zaokrąglania:from decimal import Decimal, ROUND_UP
. Inne funkcje zaokrąglaniaround(5.59, 1)
działa dobrze. Problem polega na tym, że 5.6 nie można dokładnie przedstawić w postaci binarnej zmiennoprzecinkowej.Jak mówi Vinko, możesz użyć formatowania ciągów do zaokrąglania wyświetlania.
Python ma moduł do arytmetyki dziesiętnej, jeśli tego potrzebujesz.
źródło
Otrzymasz „5,6”, jeśli to zrobisz,
str(round(n, 1))
zamiast tylkoround(n, 1)
.źródło
Możesz zmienić typ danych na liczbę całkowitą:
Następnie wyświetl liczbę, wstawiając separator dziesiętny dla ustawień regionalnych.
Jednak odpowiedź Jimmy'ego jest lepsza.
źródło
Matematyka zmiennoprzecinkowa jest podatna na drobne, ale irytujące, niedokładności precyzji. Jeśli możesz pracować z liczbami całkowitymi lub stałymi punktami, będziesz mieć gwarancję precyzji.
źródło
Spójrz na moduł Decimal
i
Dziesiętne zapewnia rodzaj operacji, które ułatwiają pisanie aplikacji, które wymagają operacji zmiennoprzecinkowych, a także muszą przedstawiać te wyniki w formacie czytelnym dla człowieka, np. Księgowość.
źródło
wypisz frajera.
źródło
To rzeczywiście duży problem. Wypróbuj ten kod:
Wyświetla 4,85. Następnie robisz:
i pokazuje 4.8. Czy wykonujesz ręczne obliczenia, dokładna odpowiedź to 4,85, ale jeśli spróbujesz:
możesz zobaczyć prawdę: punkt zmiennoprzecinkowy jest przechowywany jako najbliższa skończona suma ułamków, których mianownikami są potęgi dwóch.
źródło
Możesz użyć operatora formatu ciągu
%
, podobnie do sprintf.źródło
Działa doskonale
źródło
Robię:
W tym przypadku najpierw prawidłowo zaokrąglamy na poziomie jednostki, a następnie konwertujemy na liczbę całkowitą, aby uniknąć drukowania liczby zmiennoprzecinkowej.
więc
Myślę, że ta odpowiedź działa lepiej niż formatowanie ciągu, a także bardziej sensowne jest użycie funkcji round.
źródło
round()
W tym przypadku w ogóle bym się nie opierał . Rozważaćwyjdzie
co nie jest pożądanym wynikiem, jeśli potrzebujesz pełnego zaokrąglenia do najbliższej liczby całkowitej. Aby ominąć to zachowanie, użyj
math.ceil()
(lubmath.floor()
jeśli chcesz zaokrąglić w dół):wyjścia
Mam nadzieję, że to pomoże.
źródło
Kod:
Wynik:
źródło
Oto, gdzie widzę, że runda zawodzi. A co by było, gdybyś chciał zaokrąglić te dwie liczby do jednego miejsca po przecinku? 23,45 23,55 Moje wykształcenie było takie, że z zaokrąglenia tych wyników powinno się otrzymać: 23,4 23,6 „zasadą” jest zaokrąglanie w górę, jeśli poprzednia liczba była nieparzysta, a nie zaokrąglanie w górę, jeśli poprzednia liczba była parzysta. Funkcja round w Pythonie po prostu obcina 5.
źródło
Problem występuje tylko wtedy, gdy ostatnia cyfra to 5. Np. 0,045 jest wewnętrznie zapisywane jako 0,044999999999999 ... Można po prostu zwiększyć ostatnią cyfrę do 6 i zaokrąglić. To da pożądane rezultaty.
źródło
Inną potencjalną opcją jest:
źródło
Co powiesz na:
źródło
epsilon = .000001
zatemround(1.0/5.0, 1) + epsilon
przyjąć dokładną reprezentację 0,2 i uczynić z niej 0,00001. Równie poważne problemy wystąpiłyby, gdyby epsilon znajdował się wewnątrz funkcji rundy.