Подтвердить что ты не робот

Самый безопасный способ преобразования float в integer в python?

Математический модуль Python содержит удобные функции, такие как floor и ceil. Эти функции принимают число с плавающей запятой и возвращают ближайшее целое число ниже или выше него. Однако эти функции возвращают ответ как число с плавающей запятой. Например:

import math
f=math.floor(2.3)

Теперь f возвращает:

2.0

Каков самый безопасный способ получить целое число из этого float, не подвергая риску ошибки округления (например, если float эквивалентен 1.99999) или, возможно, я должен использовать другую функцию вообще?

4b9b3361

Ответ 1

Все целые числа, которые могут быть представлены числами с плавающей запятой, имеют точное представление. Таким образом, вы можете безопасно использовать int для результата. Неточные представления возникают только в том случае, если вы пытаетесь представить рациональное число с знаменателем, который не является степенью двух.

То, что это работает, совсем не тривиально! Это свойство представления IEEE с плавающей запятой, которое int∘floor = ⌊⋅⌋, если величина рассматриваемых чисел достаточно мала, но возможны разные представления, где int (этаж (2.3)) может быть 1.

Для цитаты из Wikipedia,

Любое целое число с абсолютным значением, меньшим или равным 2 24 может быть точно представлено в формате одиночной точности, а любое целое число с абсолютным значением, меньшим или равным 2 53 может быть точно представлен в формате двойной точности.

Ответ 2

Использовать int(your non integer number) будет гвоздь.

print int(2.3) # "2"
print int(math.sqrt(5)) # "2"

Ответ 3

Вы можете использовать круглую функцию. Если вы не используете второй параметр (# значащих цифр), я думаю, вы получите нужное поведение.

Выход IDLE.

>>> round(2.99999999999)
3
>>> round(2.6)
3
>>> round(2.5)
3
>>> round(2.4)
2

Ответ 4

Объединяя два предыдущих результата, мы имеем:

int(round(some_float))

Это преобразует float в целое число довольно надежно.

Ответ 5

То, что это работает, совсем не тривиально! Это свойство представления IEEE с плавающей запятой, которое int∘floor = ⌊⋅⌋, если величина рассматриваемых чисел достаточно мала, но возможны разные представления, где int (этаж (2.3)) может быть 1.

В этом сообщении объясняется, почему он работает в этом диапазоне.

В двойном, вы можете представлять 32-битные целые числа без каких-либо проблем. Не может быть проблем с округлением. Точнее, двойники могут представлять целые числа всех между 2 и <2 > 53 и 2 53.

Краткое описание. Двойной может хранить до 53 двоичных цифр. Когда вам нужно больше, число заполняется нулями справа.

Отсюда следует, что 53 единицы являются наибольшим числом, которое может быть сохранено без заполнения. Естественно, все (целочисленные) числа, требующие меньших цифр, могут быть сохранены точно.

Добавление 1 к 111 (пропущено) 111 (53 единицы) дает 100... 000, (53 нулей). Как известно, мы можем хранить 53 цифры, что делает крайний правый нулевой пробел.

Здесь 2 53 происходит от.


Подробнее: Нам нужно подумать о том, как работает плавающая точка IEEE-754.

  1 bit    11 / 8     52 / 23      # bits double/single precision
[ sign |  exponent | mantissa ]

Затем число рассчитывается следующим образом (за исключением особых случаев, которые здесь неактуальны):

-1 знак & times; 1.mantissa & times; 2 показатель - смещение

где bias = 2 показатель - 1 - 1, то есть 1023 и 127 для двойной/одиночной точности соответственно.

Зная, что умножение на 2 X просто сдвигает все биты X места влево, легко видеть, что любое целое число должно иметь все биты в мантиссе, которые заканчиваются справа от десятичной точки до нуля.

Любое целое число, кроме нуля, имеет двоичный вид:

1x... x, где x-es представляют биты справа от MSB (самый старший бит).

Поскольку мы исключили нуль, всегда будет MSB, который является одним из них, поэтому он не сохраняется. Чтобы сохранить целое число, мы должны привести его в вышеупомянутую форму: -1 sign & times; 1.mantissa & times; 2 exponent - смещение.

Это говорит о том же, что и сдвиг битов над десятичной точкой, пока там не останется только MSB слева от MSB. Все биты справа от десятичной точки затем сохраняются в мантиссе.

Из этого можно видеть, что мы можем хранить не более 52 двоичных цифр, кроме MSB.

Из этого следует, что наивысшее число, где все биты явно сохранены,

111(omitted)111.   that 53 ones (52 + implicit 1) in the case of doubles.

Для этого нам нужно установить показатель степени, так что десятичная точка будет сдвинута на 52 места. Если бы мы увеличили показатель на единицу, мы не сможем узнать цифру справа налево после десятичной точки.

111(omitted)111x.

По соглашению, это 0. Установка всей мантиссы в ноль, мы получаем следующий номер:

100(omitted)00x. = 100(omitted)000.

Это a 1, за которым следуют 53 нуля, 52 сохраненных и 1 добавлено из-за экспоненты.

Он представляет 2 53 который отмечает границу (как отрицательную, так и положительную), между которой мы можем точно представлять все целые числа. Если бы мы хотели добавить один к 2 53 нам нужно было бы установить неявный нуль (обозначаемый x) одним, но это невозможно.

Ответ 6

math.floor всегда будет возвращать целое число и, следовательно, int(math.floor(some_float)) никогда не будет вводить ошибки округления.

Ошибка округления может быть уже введена в math.floor(some_large_float), хотя и даже при сохранении большого числа в поплавке в первую очередь. (Большие числа могут потерять точность при хранении в поплавках.)

Ответ 7

Если вам нужно преобразовать строку с плавающей точкой в int, вы можете использовать этот метод.

Пример: от '38.0' до 38

Чтобы преобразовать это в int, вы можете разыграть его как float, а затем int. Это также будет работать для строк с плавающей точкой или целочисленных строк.

>>> int(float('38.0'))
38
>>> int(float('38'))
38

Примечание. При этом будут удалены любые цифры после запятой.

>>> int(float('38.2'))
38

Ответ 8

Другой пример кода для преобразования реального /float в целое число с использованием переменных. "vel" - это номер реального/плавающего числа и преобразован в следующий самый высокий INTEGER, "newvel".

import arcpy.math, os, sys, arcpy.da
.
.
with arcpy.da.SearchCursor(densifybkp,[floseg,vel,Length]) as cursor:
 for row in cursor:
    curvel = float(row[1])
    newvel = int(math.ceil(curvel))

Ответ 9

Поскольку вы запрашиваете "самый безопасный" способ, я предоставлю другой ответ, отличный от верхнего.

Простой способ убедиться, что вы не теряете никакой точности, это проверить, будут ли значения равны после их преобразования.

if int(some_value) == some_value:
     some_value = int(some_value)

Если значение с плавающей запятой равно 1,0, например, 1,0 равно 1. Таким образом, преобразование в int будет выполнено. А если значение с плавающей точкой равно 1.1, int (1.1) равно 1, а значение 1.1! = 1. Таким образом, значение останется с плавающей точкой, и вы не потеряете никакой точности.

Ответ 10

DF [ 'column_name'] = ДФ [ 'column_name']. astype (INT)