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

Преобразование Python в int int

В принципе, я конвертирую float в int, но у меня не всегда есть ожидаемое значение.

Здесь код, который я выполняю:

x = 2,51

print("--------- 251.0")
y = 251.0
print(y)
print(int(y))

print("--------- 2.51 * 100")
y = x * 100
print(y)
print(int(y))

print("--------- 2.51 * 1000 / 10")
y = x * 1000 / 10
print(y)
print(int(y))

print("--------- 2.51 * 100 * 10 / 10")
y = x * 100 * 10 / 10
print(y)
print(int(y))

x = 4.02
print("--------- 402.0")
y = 402.0
print(y)
print(int(y))

print("--------- 4.02 * 100")
y = x * 100
print(y)
print(int(y))

print("--------- 4.02 * 1000 / 10")
y = x * 1000 / 10
print(y)
print(int(y))

print("--------- 4.02 * 100 * 10 / 10")
y = x * 100 * 10 / 10
print(y)
print(int(y))

И вот результат (первое значение - результат операции, второе значение - int() той же операции):

--------- 251.0
251.0
251
--------- 2.51 * 100
251.0
250
--------- 2.51 * 1000 / 10
251.0
251
--------- 2.51 * 100 * 10 / 10
251.0
250
--------- 402.0
402.0
402
--------- 4.02 * 100
402.0
401
--------- 4.02 * 1000 / 10
402.0
401
--------- 4.02 * 100 * 10 / 10
402.0
401

2.51 и 4.02 - это единственные значения, которые приводят к странному поведению в диапазоне 2.50 → 5.00. Каждое другое значение двух цифр в этом диапазоне преобразуется в int без каких-либо проблем при выполнении тех же операций.

Итак, что мне не хватает, что приводит к этим результатам? Кстати, я использую Python 2.7.2.

4b9b3361

Ответ 1

2.51 * 100 = 250.999999999997

Функция int() просто усекает число в десятичной точке, давая 250. Используйте

int(round(2.51*100)) 

чтобы получить 251 как целое число. В общем случае числа с плавающей запятой не могут быть представлены точно. Поэтому следует быть осторожным с ошибками округления. Как уже упоминалось, это не специфичная для Python проблема. Это повторяющаяся проблема на всех компьютерных языках.

Ответ 2

Что каждый компьютерный ученый должен знать о арифметике с плавающей точкой

Числа с плавающей запятой не могут представлять все числа. В частности, 2.51 не может быть представлено числом с плавающей запятой и представлено рядом очень близко:

>>> print "%.16f" % 2.51
2.5099999999999998
>>> 2.51*100
250.99999999999997
>>> 4.02*100
401.99999999999994

Если вы используете int, который усекает числа, вы получаете:

250
401

Посмотрите на Decimal тип.

Ответ 3

Языки, использующие двоичные представления с плавающей запятой (Python - один), не могут точно представлять все дробные значения. Если результат вашего расчета равен 250.99999999999 (и это может быть), то при взятии целой части результат составит 250.

Каноническая статья на эту тему Что каждый компьютерный ученый должен знать о арифметике с плавающей точкой.

Ответ 4

>>> x = 2.51
>>> x*100
250.99999999999997

числа с плавающей запятой неточны. в этом случае это 250.99999999999999, что действительно близко к 251, но int() усекает десятичную часть, в этом случае 250.

вы должны взглянуть на модуль Decimal или, может быть, если вам нужно много вычислить в библиотеке mpmath http://code.google.com/p/mpmath/:),

Ответ 5

int преобразуется усечением, как уже упоминалось другими. Это может привести к тому, что ответ будет отличаться от ожидаемого. Одним из способов решения этой проблемы является проверка того, является ли результат "достаточно близким" к целому числу и, соответственно, корректировка, в противном случае - обычное преобразование. Это при условии, что вы не получите слишком много округления и ошибки расчета, что является отдельной проблемой. Например:

def toint(f):
    trunc = int(f)
    diff = f - trunc

    # trunc is one too low
    if abs(f - trunc - 1) < 0.00001:
        return trunc + 1
    # trunc is one too high
    if abs(f - trunc + 1) < 0.00001:
        return trunc - 1
    # trunc is the right value
    return trunc

Эта функция будет корректировать ошибки, возникающие при приближении к целым числам. Библиотека mpmath делает нечто подобное для чисел с плавающей точкой, близких к целым числам.