Zaokrąglić liczbę zmiennoprzecinkową w dół do najbliższej liczby całkowitej?

127

Jak sugeruje tytuł, chcę wziąć liczbę zmiennoprzecinkową i zaokrąglić ją w dół do najbliższej liczby całkowitej. Jeśli jednak nie jest to całość, ZAWSZE chcę zaokrąglić zmienną w dół, niezależnie od tego, jak blisko jest do następnej liczby całkowitej w górę. Czy jest na to sposób?

Anthony Perez
źródło
2
Możliwa trudność polega na tym, że formaty zmiennoprzecinkowe IEEE mogą przedstawiać liczby tak duże, że wielkość jest większa niż 1. Tak więc, chociaż można zaokrąglić x w dół, zaokrąglenie x + 1 w dół nie da oczekiwanego wyniku.
dmckee --- kociak ex-moderator
Proszę zamieścić kilka przykładów.
Ashwini Chaudhary

Odpowiedzi:

178

Prosty

print int(x)

zadziała również.

Makaveli
źródło
7
int (0.6) = 0 zamiast 1
Helin Wang
39
@HelinWang Dokładnie o to prosił OP.
Petr Peller
5
Wydaje się, że jest to najbardziej Pythonowe podejście.
Gyan Veda
23
Działa to dobrze w przypadku liczb dodatnich, ale liczby ujemne zostaną zaokrąglone w górę:int(-23.3) == 23
Alex Riley
2
i nie działa dla liczby spoza zakresu liczb całkowitych, takich jak 600851475143, w zasadzie oznacza błąd pamięci.
Muyide Ibukun
77

Jeden z nich powinien działać:

import math
math.trunc(1.5)
> 1
math.trunc(-1.5)
> -1
math.floor(1.5)
> 1
math.floor(-1.5)
> -2
U2EF1
źródło
14
Wynik z math.truncjest liczbą całkowitą, a wyjście math.floorjest zmiennoprzecinkową.
evedovelli
6
@evedovelli: Już nie. type(math.floor(1.51)) -> inta type(math.trunc(1.51)) -> intodpython 3.6.0
SKPS
4
Te opcje są bardziej wyraźne niż "int (x)" i dlatego są bardziej Pythonic.
Tristan,
44
x//1

//Zwraca te podłogi przegrody. Ponieważ dzielenie przez 1 nie zmienia liczby, jest to równoważne z podłogą, ale import nie jest potrzebny. Uwagi:

  1. Zwraca to liczbę zmiennoprzecinkową
  2. To zaokrągla w kierunku -∞
Huy D.
źródło
Niezły dodatek. int(-1.1) == -1jednocześnie -1.1//1 == -2.0jednak decimal.Decimal('-1.1')//1 == decimal.Decimal('-1')(jak udokumentowane roszczenia 2 nie odnosi się do decimal), więc opierając się na temat sposobów //zachowuje się nie jest w pełni stabilna, nawet dzisiaj.
Tino
28

Aby otrzymać wynik zmiennoprzecinkowy, po prostu użyj:

round(x-0.5)

Działa również w przypadku liczb ujemnych.

DmitryG
źródło
6
to jest niezwykle wyrafinowane
Alon
27

Myślę, że potrzebujesz funkcji podłogi:

podłoga matematyczna (x)

voidMainReturn
źródło
5
w pythonie 2 zwraca float, podczas gdy w pythonie 3 zwraca int
voidMainReturn
1
int (math.floor (x)) lub float (math.floor (x))
Jeff
9

wiele osób mówi, aby używać int(x), i to działa dobrze w większości przypadków, ale jest mały problem. Jeśli wynik OP to:

x = 1.9999999999999999

to się zaokrągli

x = 2

po 16. 9 to zaokrągli. To nic wielkiego, jeśli masz pewność, że nigdy nie spotkasz się z czymś takim. Ale warto o tym pamiętać.

lokilindo
źródło
17
Dzieje się tak, ponieważ w wewnętrznej reprezentacji float64 1.9999999999999999jest równy 2.0. I. e. jest już zaokrąglany, gdy tylko zostanie przetworzony na liczbę zmiennoprzecinkową, ponieważ 64-bitowa liczba zmiennoprzecinkowa nie może reprezentować tylu znaczących cyfr. Możesz to zweryfikować oceniając 1.9999999999999999 == 2.0. A jeśli podejrzewasz, że operacja równości powoduje pewne zaokrąglenia na liczbach zmiennoprzecinkowych, możesz porównać reprezentację binarną z struct.pack("d", 1.9999999999999999) == struct.pack("d", 2.0), która również jest równa.
blubberdiblub
4
A jeśli dokładnie o to ci chodzi, to nie rozumiem, co jest nie tak int(). Wartość jest już 2,0 i szczęśliwie zamieni ją na 2.
blubberdiblub
1
Jeśli intencją OP (lub kogoś, kto to czyta w przyszłości) jest użycie najbliższej liczby całkowitej (a nie wartości zaokrąglenia) z jakiegokolwiek powodu, to warto o tym pamiętać.
lokilindo
3
@lokilindo Nie ma to jednak nic wspólnego int(), ma to związek wyłącznie z niewłaściwym użyciem programufloat , który 1.9999999999999999jest zaokrąglany w górę 2.0 w czasie kompilacji (podczas gdy int()jest wywoływana w czasie wykonywania). Jeśli użyjesz odpowiedniego typu danych dla zmiennej, wszystko działa zgodnie z oczekiwaniami: int(decimal.Decimal('1.9999999999999999999999999999999999999999999999999999999'))daje1
Tino
6

Jeśli nie chcesz importować matematyki, możesz użyć:

int(round(x))

Oto fragment dokumentacji:

>>> help(round)
Help on built-in function round in module __builtin__:

round(...)
    round(number[, ndigits]) -> floating point number

    Round a number to a given precision in decimal digits (default 0 digits).
    This always returns a floating point number.  Precision may be negative.
Tyler
źródło
Dziękuję za odpowiedź. Następnym razem uzyskasz lepszy odbiór, jeśli napiszesz odpowiedni kod (w nawiasach) i podasz dokumentację.
Geoff
2
roundbyła już omawiana i odrzucana jako odpowiedź, gdy to pytanie zostało zadane rok temu. OP chce math.floor.
Adam Smith
3

Jeśli pracujesz z numpy, możesz użyć następującego rozwiązania, które działa również z liczbami ujemnymi (działa również na tablicach)

import numpy as np
def round_down(num):
    if num < 0:
        return -np.ceil(abs(num))
    else:
        return np.int32(num)
round_down = np.vectorize(round_down)

round_down([-1.1, -1.5, -1.6, 0, 1.1, 1.5, 1.6])
> array([-2., -2., -2.,  0.,  1.,  1.,  1.])

Myślę, że zadziała również, jeśli użyjesz mathmodułu zamiast numpymodułu.

Panie Poin
źródło
1

Nie wiem, czy to rozwiązałeś, ale właśnie natknąłem się na to pytanie. Jeśli chcesz pozbyć się kropek dziesiętnych, możesz użyć int (x), co wyeliminuje wszystkie cyfry dziesiętne. Nie ma potrzeby używania round (x).

Gaahbon
źródło
1

Po prostu zaokrąglij (x-0,5), co zawsze zwróci następną zaokrągloną w dół wartość całkowitą twojego Float. Możesz również łatwo zaokrąglić w górę, wykonując rundę (x + 0,5)

Dominic Nagel
źródło
-1

To może być bardzo proste, ale czy nie można by po prostu zaokrąglić do minus 1? Na przykład:

number=1.5
round(number)-1
> 1

źródło
4
To daje błędną odpowiedź dla całych liczb całkowitych. Na przykład zaokrąglenie 2,0 w ​​górę to 2, a jeśli
odejmiemy
@PascalCuoq Nie rozumiem twojego problemu. Czy chcesz, aby wynik był 1.0? Ponieważ OP wyraźnie chciał zaokrąglić, a następnie policzyć do najbliższej integer.
bad_keypoints
1
@bad_keypoints Nie sądzę, żeby PO chciał zaokrąglić 2,0 do 1.
Pascal Cuoq
@PascalCuoq przepraszam, właśnie spojrzałem na odpowiedź w wątku komentarzy, której jesteśmy.
bad_keypoints
-3

Użyłem tego kodu, w którym odejmujesz 0,5 od liczby, a kiedy ją zaokrąglasz, jest to pierwotna liczba zaokrąglona w dół.

okrągły (a-0,5)

user10555509
źródło
1
Jaka jest różnica od tej istniejącej odpowiedzi ?
xskxzr