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?


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ż.


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

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 -∞

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.


6
to jest niezwykle wyrafinowane
Alon


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ć.


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.

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.


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).


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)


-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

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.