Округлить число с плавающей запятой до ближайшего целого?

128

Как следует из названия, я хочу взять число с плавающей запятой и округлить его до ближайшего целого числа. Однако, если это не целое, я ВСЕГДА хочу округлить переменную в меньшую сторону, независимо от того, насколько она близка к следующему целому числу вверх. Есть ли способ сделать это?

Энтони Перес
источник
2
Возможная трудность состоит в том, что форматы с плавающей запятой IEEE могут представлять числа настолько большие, что грандиозность больше 1. Так что, хотя вы можете округлить x в меньшую сторону, округление x + 1 в меньшую сторону не даст вам ожидаемого результата.
dmckee --- котенок экс-модератора
Выложите, пожалуйста, несколько примеров.
Ашвини Чаудхари

Ответы:

179

просто

print int(x)

тоже будет работать.

Makaveli
источник
7
int (0.6) = 0, а не 1
Хелин Ван
39
@HelinWang Это именно то, о чем просил OP.
Петр Пеллер
5
Это похоже на самый питонический подход.
Gyan Veda
23
Это хорошо работает для положительных чисел, но отрицательные числа будут округлены int(-23.3) == 23
Alex Riley
2
и не работает для чисел, выходящих за пределы целочисленного диапазона, например 600851475143, в основном указывает на ошибку памяти.
Muyide Ibukun
77

Один из них должен работать:

import math
math.trunc(1.5)
> 1
math.trunc(-1.5)
> -1
math.floor(1.5)
> 1
math.floor(-1.5)
> -2
U2EF1
источник
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 03
4
Эти параметры более явны, чем int (x), и, следовательно, более питоничны.
Тристан
44
x//1

//Оператор возвращает слово деления. Поскольку деление на 1 не меняет вашего числа, это эквивалентно floor, но импорт не требуется. Ноты:

  1. Это возвращает поплавок
  2. Это округляется до -∞
Хай Д
источник
Хорошее дополнение. int(-1.1) == -1в то время как -1.1//1 == -2.0однако decimal.Decimal('-1.1')//1 == decimal.Decimal('-1')(как указано в документации, утверждение 2 неверно decimal), поэтому полагаться на то, как //ведет себя, не является полностью стабильным даже сегодня.
Tino
28

Чтобы получить результат с плавающей запятой, просто используйте:

round(x-0.5)

Это также работает для отрицательных чисел.

DmitryG
источник
6
чрезвычайно изощренно
Алон
27

Думаю, нужна функция пола:

Math.floor (х)

voidMainReturn
источник
5
в python 2 он возвращает float, а в python 3 возвращает int
voidMainReturn
1
int (math.floor (x)) или float (math.floor (x))
Джефф
9

многие люди говорят использовать int(x), и это работает в большинстве случаев, но есть небольшая проблема. Если результат OP:

x = 1.9999999999999999

он будет округлен до

x = 2

после 16-го будет 9 раунд. В этом нет ничего страшного, если вы уверены, что никогда не встретите такую ​​вещь. Но об этом нужно помнить.

lokilindo
источник
17
Это потому, что 1.9999999999999999фактически равно 2.0во внутреннем представлении float64. I. e. оно уже округлено, как только преобразовано в число с плавающей запятой, поскольку 64-битное число с плавающей запятой не может представлять такое количество значащих цифр. Вы можете убедиться в этом, выполнив оценку 1.9999999999999999 == 2.0. И если вы подозреваете, что операция равенства выполняет некоторое округление с плавающей запятой, вы можете сравнить двоичное представление с struct.pack("d", 1.9999999999999999) == struct.pack("d", 2.0), которое также равно.
blubberdiblub
4
И если это именно ваша точка зрения, то я не понимаю, что не так int(). Значение уже 2,0, и оно
успешно
1
Если OP (или кто-то еще прочтет это в будущем) намерен использовать ближайшее целое число (а не округленное значение) по какой-либо причине, то об этом следует помнить.
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), и он удалит все десятичные цифры. Нет необходимости использовать round (x).

Gaahbon
источник
1

Просто округлите (x-0,5), это всегда будет возвращать следующее округленное в меньшую сторону целочисленное значение вашего Float. Вы также можете легко округлить до округления (x + 0,5)

Доминик Нагель
источник
-1

Это может быть очень просто, но не могли бы вы просто округлить его до минус 1? Например:

number=1.5
round(number)-1
> 1

источник
4
Это дает неправильный ответ для целых чисел. Например, округленное значение 2,0 равно 2, а если вычесть 1, получится неверный результат 1.
Паскаль Куок
@PascalCuoq Я не понимаю твоей проблемы. Вы хотите 1.0 в результате? Потому что OP явно хотел округлить это число до ближайшего integer.
bad_keypoints
1
@bad_keypoints Я не думаю, что ОП хочет округлить 2,0 до 1.
Паскаль Куок,
@PascalCuoq, извините, я только что посмотрел на ответ в ветке комментариев, к которой мы относимся.
bad_keypoints
-3

Я использовал этот код, где вы вычитаете 0,5 из числа, и когда вы его округляете, это исходное число, округленное в меньшую сторону.

круглая (а-0,5)

user10555509
источник
1
В чем отличие от существующего ответа ?
xskxzr