Округніть номер плаваючої точки до найближчого цілого?


127

Як випливає з назви, я хочу взяти число з плаваючою комою і округлити його до найближчого цілого числа. Однак, якщо це не ціле, Я ЗАВЖДИ хочу округляти змінну, незалежно від того, наскільки вона близька до наступного цілого числа вгору. Чи є спосіб це зробити?


2
Можлива складність полягає в тому, що формати IEEE з плаваючою точкою можуть представляти числа настільки великі, що деталізація більша за 1. Так що, хоча ви можете заокруглювати х вниз, округлення x + 1 вниз не дасть вам очікуваного результату.
dmckee --- кошеня колишнього модератора

Будь ласка, опублікуйте кілька прикладів.
Ашвіні Шадхарі

Відповіді:


178

Простий

print int(x)

також працюватиме.


7
int (0,6) = 0, а не 1
Хелін Ван

39
@HelinWang Саме про це попросили ОП.
Петро Пеллер

5
Це здається найбільш пітонічним підходом.
Gyan Veda

23
Це добре підходить для позитивних чисел, але негативні цифри будуть округлені:int(-23.3) == 23
Алекс Райлі

2
і не працює для числа, що перевищує цілий діапазон, такий як 600851475143, він в основному позначає помилку пам'яті.
Муїде Ібукун

77

Один з них повинен працювати:

import math
math.trunc(1.5)
> 1
math.trunc(-1.5)
> -1
math.floor(1.5)
> 1
math.floor(-1.5)
> -2

14
Вихід з math.trunc- ціле число, а вихід math.floor- поплавок.
evedovelli

6
@evedovelli: Насправді вже не так. type(math.floor(1.51)) -> intі type(math.trunc(1.51)) -> intза станомpython 3.6.0
SKPS

4
Ці параметри є більш явними, ніж "int (x)", а значить, більш пітонічні.
Трістан

44
x//1

//Оператор повертає слово поділу. Оскільки ділення на 1 не змінює ваше число, це еквівалентно поверху, але імпорт не потрібен. Примітки:

  1. Це повертає поплавок
  2. Це кругообіг до -∞

Приємне доповнення. int(-1.1) == -1в той час як , -1.1//1 == -2.0проте decimal.Decimal('-1.1')//1 == decimal.Decimal('-1')(як описано, твердження 2 не відноситься до decimal), тому покладатися на те , як //веде себе не цілком стабільна, навіть сьогодні.
Тіно

28

Щоб отримати результат з плаваючою комою, просто скористайтеся:

round(x-0.5)

Він працює і для від'ємних чисел.


6
надзвичайно витончений, це
Алон


9

багато хто каже, що використовувати int(x), і це працює нормально для більшості випадків, але є невелика проблема. Якщо результат ОП:

x = 1.9999999999999999

вона округлятиметься до

x = 2

після 16-го 9 він завершиться. Це не велика справа, якщо ви впевнені, що ніколи не натрапите на таке. Але це щось пам’ятати.


17
Це тому 1.9999999999999999, що насправді є рівним 2.0у внутрішньому представленні float64. І. е. він уже округлюється, як тільки він розбирається на поплавок, оскільки 64-бітний поплавок не може представляти стільки значущих цифр. Ви можете перевірити це, оцінюючи 1.9999999999999999 == 2.0. І якщо ви підозрюєте, що операція рівняння робить деяке округлення поплавків, ви можете порівняти двійкове представлення з struct.pack("d", 1.9999999999999999) == struct.pack("d", 2.0), яке також дорівнює.
blubberdiblub

4
І якщо це саме ваш пункт, я не бачу, у чому справа int(). Значення вже 2,0, і воно щасливо перетворить його на 2.
blubberdiblub

1
Якщо ОП (або хто читає це в майбутньому) має намір використовувати найближче ціле число (а не значення округлення) з будь-якої причини, то це слід пам’ятати.
lokilindo

3
@lokilindo Але це не має нічого спільного int(), це стосується виключно неправильного використанняfloat , як 1.9999999999999999це округлюється до 2.0 моменту компіляції (поки int()називається час виконання). Якщо ви використовуєте правильний тип даних для змінної, все працює так, як очікувалося: int(decimal.Decimal('1.9999999999999999999999999999999999999999999999999999999'))дає1
Тіно

6

Якщо ви не хочете імпортувати математику, ви можете використовувати:

int(round(x))

Ось фрагмент документації:

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

Дякую за вашу відповідь. Наступного разу ви отримаєте кращий прийом, якщо напишете належний код (закрийте круглі дужки) та надасте трохи документації.
Джефф

2
roundвже було обговорено та відхилено як відповідь, коли це питання було задано рік тому. ОП хоче math.floor.
Адам Сміт

3

Якщо ви працюєте з numpy, ви можете скористатися наступним рішенням, яке також працює з від'ємними числами (воно також працює над масивами)

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

Я думаю, це також спрацює, якщо ви просто використовуєте mathмодуль замістьnumpy модуля.


1

Не знаю, чи вирішили ви це, але я просто натрапляю на це питання. Якщо ви хочете позбутися десяткових знаків, ви можете використовувати int (x), і це усуне всі десяткові цифри. Не потрібно використовувати круглий (x).


1

Просто зробіть круглий (x-0,5), це завжди поверне наступне округлене значення Integer вашого Float. Ви також можете легко округлити, зробивши круглий (х + 0,5)


-1

Це може бути дуже просто, але хіба ви не могли просто його округлити тоді мінус 1? Наприклад:

number=1.5
round(number)-1
> 1

4
Це дає неправильну відповідь для цілих чисел. Наприклад, 2,0 округлено дорівнює 2, і якщо відняти 1, ви отримаєте невірний результат 1.
Паскаль Куок

@PascalCuoq Я не розумію вашої проблеми. Ви хочете отримати результат 1,0? Тому що ОП явно хотів округлити потім номер до найближчого integer.
bad_keypoints

1
@bad_keypoints Я не думаю, що ОП хоче пройти 2,0 до 1
Паскаль Куок

@PascalCuoq Вибачте, я просто озирнувся на відповідь у коментарі, про який ми є.
bad_keypoints

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.