Próbowałem zaokrąglać długie liczby zmiennoprzecinkowe, takie jak:
32.268907563;
32.268907563;
31.2396694215;
33.6206896552;
...
Jak dotąd bez powodzenia. Próbowałem math.ceil(x)
, math.floor(x)
(mimo że zaokrąglić w górę lub w dół, co jest nie to, czego szukam) i round(x)
które nie działało (wciąż unosić numery).
Co mógłbym zrobić?
EDYCJA: KOD:
for i in widthRange:
for j in heightRange:
r, g, b = rgb_im.getpixel((i, j))
h, s, v = colorsys.rgb_to_hsv(r/255.0, g/255.0, b/255.0)
h = h * 360
int(round(h))
print(h)
int(x)
Odpowiedzi:
Zaokrągli go i zmieni na liczbę całkowitą
EDYTOWAĆ:
Nie przypisujesz int (round (h)) do żadnej zmiennej. Kiedy wywołujesz int (round (h)), zwraca liczbę całkowitą, ale nic więcej nie robi; musisz zmienić ten wiersz dla:
Aby przypisać nową wartość do h
EDYCJA 2:
Jak powiedział @plowman w komentarzach, Python's
round()
nie działa tak, jak normalnie by się tego spodziewał, a to dlatego, że sposób, w jaki liczba jest przechowywana jako zmienna, zwykle nie jest taki, jak na ekranie. Istnieje wiele odpowiedzi, które wyjaśniają to zachowanie:round () nie wydaje się poprawnie zaokrąglać
Jednym ze sposobów uniknięcia tego problemu jest użycie wartości dziesiętnych zgodnie z poniższą odpowiedzią: https://stackoverflow.com/a/15398691/4345659
Aby ta odpowiedź działała poprawnie bez użycia dodatkowych bibliotek, wygodne byłoby użycie niestandardowej funkcji zaokrąglania. Po wielu poprawkach wymyśliłem następujące rozwiązanie, które, o ile testowałem, pozwoliło uniknąć wszystkich problemów związanych z przechowywaniem. Opiera się na użyciu reprezentacji ciągu uzyskanej za pomocą
repr()
(NOTstr()
!). Wygląda na zrzędliwego, ale to był jedyny sposób, w jaki udało mi się rozwiązać wszystkie sprawy. Działa zarówno z Python2, jak i Python3.Testy:
Wreszcie poprawiona odpowiedź brzmi:
EDYCJA 3:
Testy:
Gotcha polega na tym, że
dec
-te miejsce po przecinku może wynosić 9, a jeślidec+1
-ta cyfra> = 5, 9 stanie się 0, a 1 należy przenieść nadec-1
-tą cyfrę.Jeśli weźmiemy to pod uwagę, otrzymujemy:
W sytuacji opisanej powyżej
b = 10
i poprzedniej wersji po prostu concatenatea
ib
które doprowadziłoby do konkatenacji10
gdzie tylna 0 zniknie. Ta wersja przekształcab
się na właściwe miejsce po przecinku na podstawiedec
, jako prawidłowego przeniesienia.źródło
int(round(4.5))
zaokrągla w dół do 4, a jednocześnieint(round(4.500001))
zaokrągla do 5.round(x)
wystarczy w Pythonie 3.6.2 (i może także w niższych wersjach). Wynik jest już typu int. Uwaga:round(x, n)
będzie typu float.Zastosowanie
round(x, y)
. Zaokrągli liczbę w górę do żądanego miejsca po przecinku.Na przykład:
źródło
round(value,significantDigit)
jest zwykłym rozwiązaniem, jednak nie działa tak, jak można by się tego spodziewać z perspektywy matematycznej, gdy zaokrąglone wartości kończą się na5
. Jeśli5
cyfra znajduje się tuż za tą, do której chcesz zaokrąglić, wartości te są tylko czasami zaokrąglane w górę zgodnie z oczekiwaniami (tzn.8.005
Zaokrąglanie do dwóch cyfr dziesiętnych daje8.01
). Dla niektórych wartości z powodu dziwactwa matematyki zmiennoprzecinkowej są one zaokrąglane w dół!to znaczy
Dziwne.
Zakładając, że Twoim celem jest wykonanie tradycyjnego zaokrąglania dla statystyk w nauce, jest to przydatne opakowanie, aby
round
funkcja działała zgodnie z oczekiwaniami i wymagałaimport
dodatkowych rzeczyDecimal
.Aha! Na tej podstawie możemy wykonać funkcję ...
Zasadniczo dodaje to wartość, która ma być mniejsza niż najmniej podana cyfra ciągu, którego próbujesz użyć
round
. Dodając tę niewielką ilość,round
w większości przypadków zachowuje zachowanie, a jednocześnie zapewnia, że cyfra gorsza od tej, do której jest zaokrąglana, zaokrągla w5
górę, a jeśli jest4
to zaokrągla w dół.Podejście polegające na użyciu
10**(-len(val)-1)
było celowe, ponieważ jest to największa mała liczba, jaką można dodać, aby wymusić przesunięcie, jednocześnie zapewniając, że dodana wartość nigdy nie zmienia zaokrąglenia, nawet jeśli.
brakuje dziesiętnego . Mógłbym użyć tylko10**(-len(val))
warunku,if (val>1)
aby odjąć1
więcej ... ale łatwiej jest po prostu zawsze odjąć,1
ponieważ nie zmieni to zbytnio odpowiedniego zakresu liczb dziesiętnych, które to obejście może poprawnie obsłużyć. To podejście zakończy się niepowodzeniem, jeśli twoje wartości osiągną granice danego typu, to się nie powiedzie, ale dla prawie całego zakresu prawidłowych wartości dziesiętnych powinno działać.Aby to zrobić, możesz również użyć biblioteki dziesiętnej , ale proponuję opakowanie jest prostsze i może być preferowane w niektórych przypadkach.
Edycja: Dzięki Blckknght za wskazanie, że wielkość
5
marginesu występuje tylko dla niektórych wartości. Również wcześniejsza wersja tej odpowiedzi nie była wystarczająco wyraźna, aby dziwne zaokrąglanie występowało tylko wtedy, gdy cyfra bezpośrednio gorsza od cyfry, do której zaokrąglasz, ma5
.źródło
5
ponieważ ich ostatnia cyfra zawsze będzie zaokrąglać w dół. To nie jest przypadek szybkiego testu po prostu zrobił z numerami jak1.5
,2.5
,3.5
i tak dalej, i1.05
,1.15
,1.25
,1.35
zaokrąglenia do jednego miejsca po przecinku. Pierwszy zestaw (dokładne zaokrąglenie połówek do małych liczb całkowitych) zawsze zaokrągla do parzystej liczby całkowitej. Ten ostatni zestaw nie zaokrągla się konsekwentnie, prawdopodobnie z powodu niedokładnych reprezentacji binarnych niektórych wartości. Elementy zmiennoprzecinkowe, które mają dokładne reprezentacje binarne, takie jak1.25
okrągły, mają nawet najmniej znaczącą cyfrę, ale pozostałe wydają się zaokrąglać losowo.round(4.0005,3)
daje4.0
iround(1.0005,3)
daje1.0
, aleround(2.0005,3)
daje2.001
iround(3.0005,3)
daje3.001
. Ale właśnie dlatego moje proponowane rozwiązanie jest konieczne ... nie wiesz, czego oczekiwać od rundy giełdowej, w tym znaczącym przypadku!, digits
na końcu tego oświadczenia zwrotnego? Gra słów nie przeznaczona. ( mam na myśli to znaczy)W przypadku pozytywów spróbuj
Aby działało również w przypadku negatywów, spróbuj
int()
działa jak funkcja podłogi i dlatego możesz wykorzystać tę właściwość. To zdecydowanie najszybszy sposób.źródło
>>> x=-0.999
>>> int(x), round(x), int(x+0.5)
(0, -1.0, 0)
Nie działa tylko Python okrągłej połowy nawet , jak zalecono w IEEE 754 ?
Zachowaj ostrożność przedefiniowując lub używając „niestandardowego” zaokrąglenia…
(Zobacz także https://stackoverflow.com/a/33019948/109839 )
źródło
Round half to even
nie jest absolutnie zalecany przez IEEE 754, ale jest tylko jedną z kilku opcji zaokrąglania opisanych w normie .Round to nearest, ties away from zero
(tj. zachowanie, którego oczekuje większość ludzi) jest również opcją i jest domyślne, na przykład w C / C ++.round
jest wyjaśnione) i robi to zgodnie ze sposobem, w jaki zalecana jest „okrągła połowa do parzystej” pracować (lub opisać) według normy.Możesz także użyć numpy, zakładając, że używasz python3.x. Oto przykład
źródło
Twoje rozwiązanie dzwoni bez podania drugiego argumentu (liczba miejsc dziesiętnych)
co jest znacznie lepszym wynikiem niż
Z dokumentacji Pythona na https://docs.python.org/3/library/functions.html#round
źródło
Jeśli potrzebujesz (na przykład) dwucyfrowego przybliżenia dla A,
int(A*100+0.5)/100.0
zrobisz to, czego szukasz.Jeśli potrzebujesz przybliżenia trzycyfrowego, pomnóż go i podziel przez 1000 itd.
źródło
Coś takiego powinno również działać
źródło
W tym celu proponuję po prostu wykonać następujące czynności -
To da ci najbliższą liczbę całkowitą.
Mam nadzieję że to pomoże!!
źródło
Korzystam i mogę doradzić następujące rozwiązanie (python3.6):
Działa dobrze w przypadku liczb połówkowych (dodatnich i ujemnych) i działa nawet szybciej niż int (round (x)):
źródło