Каждый объект с плавающей запятой точно представляет одно число (или специальное значение, например, NaN). Объекты с плавающей точкой не представляют приближения.
Правильный способ думать о числах с плавающей точкой состоит в том, что значения с плавающей точкой являются точными числами, но операции с плавающей точкой приближаются к реальной арифметике.
Python точно не определяет арифметику с плавающей точкой; каждая реализация Python может использовать базовую арифметику платформы, на которой она реализована. Обычно используются форматы IEEE 754, хотя операции могут не полностью соответствовать IEEE 754. Чтобы проиллюстрировать, что происходит с вашим кодом, я буду использовать базовый 64-разрядный двоичный код с плавающей точкой IEEE-754.
При обработке исходного текста 0.5
он преобразуется в число с плавающей запятой. Обратите внимание, что преобразование является операцией, так же как сложение или умножение являются операциями. Символы интерпретируются как десятичное число, и преобразование создает число с плавающей запятой, которое является ближайшим к числу, представленному десятичным числом. В этом случае 0.5
представляет половину, и это точно представлено в двоичной форме с плавающей запятой, поэтому результат равен точно 0,5.
Затем [0.5] * 10
создает список, содержащий десять копий по 0,5, а sum
добавляет их. Все сложения, выполненные в этом суммировании, являются точными, поскольку формат с плавающей точкой может точно представлять 0,5, 1, 1,5, 2 и т. Д. Таким образом, результат равен именно 5, и сравнение с 5 дает истину.
С другой стороны, при обработке исходного текста 0.1
эта десятичная цифра представляет одну десятую, что не может быть точно представлено. В результате преобразования получается ближайшее представимое значение, равное 0,1000000000000000055511151231257827021181583404541015625.
Когда sum
добавляет десять копий, сложение не всегда может быть выполнено точно. Точное добавление первых двух, добавление 0.1000000000000000055511151231257827021181583404541015625 к 0.1000000000000000055511151231257827021181583404541015625 приводит к 0.200000000000000011102230246251565404236316680. Однако при добавлении 0.200000000000000011102230246251565404236316680908203125 к 0.1000000000000000055511151231257827021181583404541015625, результат составляет 0,3000000000000000444089209850062616169125667236. Во время этого добавления биты в добавлении переносятся в новую позицию (операнды находятся под ¼, но результат больше ¼ - сложение переносится в позицию Since. Поскольку формат с плавающей запятой имеет только фиксированное число битов ( 53) доступное для значения, операция должна была отбрасывать младший бит. При этом он немного изменил результат. Так что это сложение только приблизительное.
Поскольку эти добавления продолжаются, окончательное значение составляет 0,999999999999999988897769753748434595763683319091796875. Если сравнить с 1, результат будет ложным.