Математический модуль Python содержит удобные функции, такие как floor
& ceil
. Эти функции принимают число с плавающей запятой и возвращают ближайшее целое число ниже или выше его. Однако эти функции возвращают ответ в виде числа с плавающей запятой. Например:
import math
f=math.floor(2.3)
Теперь f
возвращается:
2.0
Какой самый безопасный способ получить целое число из этого числа с плавающей точкой, без риска ошибки округления (например, если число с плавающей точкой эквивалентно 1.99999) или, возможно, мне следует использовать другую функцию в целом?
python
math
integer
python-2.x
Боаз
источник
источник
math.floor
возвращает число с плавающей запятой в v2.6 , но оно возвращает целое число в v3 . На данный момент (почти через шесть лет после ОП) эта проблема может появляться редко.Ответы:
Все целые числа, которые могут быть представлены числами с плавающей запятой, имеют точное представление. Так что вы можете смело использовать
int
результат. Неточные представления возникают, только если вы пытаетесь представить рациональное число со знаменателем, который не является степенью двойки.То, что это работает, совсем не тривиально! Это свойство представления IEEE с плавающей точкой, что int∘floor = ⌊⋅⌋, если величина рассматриваемых чисел достаточно мала, но возможны разные представления, где int (floor (2.3)) может быть 1.
Цитировать из Википедии ,
источник
Используйте
int(your non integer number)
это прибьет это.источник
floor
int
int(-2.3)
в дистрибутиве Python Canopy 2.7.6 и получил,-2
как и ожидалось. Целые числа могут быть отрицательными, так же, как в формальном определении по математике.int(-2.3)
дает,-2
как вы говорите, потому что это округляет0
, то есть вверх в этом случае. Напротив, используется оригинальный вопросmath.floor
, который всегда округляется:math.floor(-2.3)
дает-3.0
.math.floor
, и этот ответ показывает, как преобразовать число с плавающей точкой в целое число. Возьмите поплавокmath.floor
иint
int(math.floor(2.3))
Вы можете использовать функцию округления. Если вы не используете второй параметр (количество значащих цифр), я думаю, вы получите желаемое поведение.
IDLE выход.
источник
round
также возвращает число с плавающей запятой, по крайней мере, в Python 2.6.round
иfloor
возвращают целые числа в Python 3.x. Поэтому я предполагаю, что вопрос касается Python 2.x.int(round(2.65))
?round(6.5)
дает 6? Кажется, что это своего родаceil()
плавающее число, когда во всех остальных случаях после десятичной дроби сразу после 5 (или больше). Почему это не работает в этом случае? или любой другой случай, когда число заканчивается на шесть, а после десятичной запятой есть 5 ...Объединяя два предыдущих результата, мы имеем:
Это превращает число с плавающей точкой в целое число довольно надежно.
источник
float
представление числа больше, чемint
может удержать нормаль . В Python 2 естьfloat
значения, которые вы можете представить только с помощьюlong
(после округления)?int()
функция производит или,int
или наlong
основе того, что нужно ...Этот пост объясняет, почему он работает в этом диапазоне .
В двойном выражении вы можете без проблем представлять 32-битные целые числа. Там не может быть никаких вопросов округления. Точнее, double может представлять все целые числа от 2 53 до -2 53 включительно. .
Краткое объяснение : двойной может хранить до 53 двоичных цифр. Когда вам требуется больше, число дополняется нулями справа.
Отсюда следует, что 53 единицы - это наибольшее число, которое можно хранить без заполнения. Естественно, все (целые) числа, требующие меньше цифр, могут быть сохранены точно.
Добавление одного к 111 (опущено) 111 (53) приводит к 100 ... 000, (53 нуля). Как мы знаем, мы можем хранить 53 цифры, что делает заполнение нуля самым правым.
Отсюда 2 53 .
Более подробно: нам нужно рассмотреть, как работает IEEE-754 с плавающей запятой.
Затем число рассчитывается следующим образом (за исключением особых случаев, которые здесь не имеют значения):
где смещение = 2 экспонента - 1 - 1 , то есть 1023 и 127 для двойной / одинарной точности соответственно.
Зная, что умножение на 2 X просто сдвигает все биты X влево, легко видеть, что любое целое число должно иметь все биты в мантиссе, которые заканчиваются справа от десятичной точки до нуля.
Любое целое число, кроме нуля, имеет следующую форму в двоичном виде:
Поскольку мы исключили ноль, всегда будет единица MSB, поэтому она не сохраняется. Чтобы сохранить целое число, мы должны привести его в вышеупомянутую форму: -1 знак × 1.Mantissa × 2 экспонента - смещение .
Это то же самое, что сдвигать биты над десятичной точкой, пока слева от MSB не будет только MSB. Все биты справа от десятичной точки затем сохраняются в мантиссе.
Отсюда видно, что мы можем хранить не более 52 двоичных цифр, кроме MSB.
Отсюда следует, что наибольшее число, в котором все биты хранятся явно
Для этого нам нужно установить показатель степени так, чтобы десятичная точка была смещена на 52 позиции. Если бы мы увеличили показатель степени на единицу, мы не смогли бы узнать цифру справа налево после десятичной точки.
По соглашению, это 0. Установив всю мантиссу на ноль, мы получим следующее число:
Это 1 с последующими 53 нулями, 52 сохраненными и 1 добавленными из-за показателя степени.
Это представляет 2 53 , который отмечает границу (и отрицательную и положительную), между которой мы можем точно представить все целые числа. Если бы мы хотели добавить один к 2 53 , мы должны были бы установить неявный ноль (обозначенный как
x
) на один, но это невозможно.источник
math.floor
всегда будет возвращать целое число и, следовательноint(math.floor(some_float))
, никогда не приведет к ошибкам округления.Ошибка округления может быть уже внесена
math.floor(some_large_float)
, или даже при первом сохранении большого числа в плавающей запятой. (Большие числа могут потерять точность при хранении в числах с плавающей запятой.)источник
int
иfloor
возвращать разные значения для отрицательных чисел, конечно.Если вам нужно преобразовать строку с плавающей точкой в int, вы можете использовать этот метод.
Пример:
'38.0'
к38
Чтобы преобразовать это в int, вы можете разыграть его как float, а затем int. Это также будет работать для строк с плавающей точкой или целочисленных строк.
Примечание . Это приведет к удалению любых чисел после запятой.
источник
Другой пример кода для преобразования real / float в целое число с использованием переменных. «vel» - это действительное число / число с плавающей запятой, которое преобразуется в следующий по величине INTEGER, «newvel».
источник
Поскольку вы запрашиваете «самый безопасный» способ, я предоставлю другой ответ, отличный от верхнего.
Простой способ убедиться, что вы не теряете никакой точности, это проверить, будут ли значения равны после их преобразования.
Например, если число с плавающей запятой равно 1,0, 1,0 равно 1. Таким образом, преобразование в int будет выполнено. И если значение с плавающей точкой равно 1.1, int (1.1) равно 1, а значение 1.1! = 1. Таким образом, значение останется с плавающей точкой, и вы не потеряете никакой точности.
источник
DF [ 'column_name'] = ДФ [ 'column_name']. astype (INT)
источник