Какое правило округления использует Python для преобразования числа с плавающей запятой в целое число? - PullRequest
1 голос
/ 20 июня 2020

Изменить: После публикации этого вопроса стало очевидно, что моя память о том, что происходило на более старых языках, была ошибочной и что нет никакой фундаментальной разницы, поскольку я только что проверил, запустив эквивалентную программу Fortran. Короче говоря, моя посылка была неверной. Я решил не задавать этот вопрос, чтобы другие, у кого есть вопросы, могли видеть ответы.

Исходное сообщение: В отличие от более ранних языков программирования, с которыми я работал (Fortran, C , IDL, et c.), Кажется, что Python немного умнее в отношении округления при преобразовании чисел с плавающей точкой в ​​целые числа. Например, на многих языках эквивалент

x = 1./3.
y = 3.*x
print( int(y))

дает 0 из-за усечения при вычислении 1/3. Но Python возвращает 1, что обычно является предпочтительным результатом. Но как Python определяет, когда игнорировать небольшие ошибки усечения, а когда нет? Я обнаружил, что существует очевидный порог точности:

> int(10.999999999999999)
10
> int(10.9999999999999999)
11

, где во второй строке есть еще одна «9». Является ли пороговая точность фиксированной, определенной особенностью языка или зависит от реализации?

Было бы неплохо лучше понять, когда можно Python делать «правильные вещи», а когда нельзя. Как уже упоминалось, в старых языках эта проблема требовала постоянного пристального внимания, потому что вы знали, что даже малейшая ошибка усечения может дать вам другой целочисленный результат, и даже порядок деления и / или умножения иногда имеет значение.

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

1 Ответ

2 голосов
/ 20 июня 2020

При разделении Python3 .x с оператором / всегда возвращает float. Вот почему 1/3 не усекается до 0.

Во второй части вашего вопроса на самом деле это не функция int, которая округляет число. Вы просто не можете представить float с такой точностью, поэтому оно округляется до 11 перед передается функции int:

>>> 10.999999999999999
10.999999999999998
>>> 10.9999999999999999
11.0
...