Начиная с Python 2.7 и 3.1, Python отображает числа с плавающей запятой, используя кратчайшее представление, которое при оценке дает одно и то же число с плавающей запятой. От documentation:
Python теперь использует алгоритм Дэвида Гей для нахождения кратчайшего представления с плавающей точкой, который не меняет его значения. Это должно помочь смягчить некоторые путаницы, связанные с двоичными числами с плавающей запятой.
Значимость легко видна с номером 1.1
, который не имеет точного эквивалента в двоичной плавающей запятой. Так как нет точного эквивалента, выражение, подобное float('1.1')
, оценивается до ближайшего представляемого значения, которое равно 0x1.199999999999ap+0
в шестнадцатеричном виде или 1.100000000000000088817841970012523233890533447265625
в десятичном формате. Это ближайшее значение было и остается в последующих вычислениях с плавающей запятой.
Что нового рядом? Раньше Python использовал простой подход. Значение repr(1.1)
было рассчитано как format(1.1, '.17g')
, которое оценивалось до '1.1000000000000001'
. Преимущество использования 17 цифр состояло в том, что он полагался на гарантии IEEE-754, чтобы гарантировать, что eval(repr(1.1))
будет в оба конца точно до его первоначального значения. Недостаток заключается в том, что многие люди обнаружили, что результат путают (ошибочные внутренние ограничения двоичного представления с плавающей запятой как проблемы с самим Python).
Новый алгоритм для repr(1.1)
умнее и возвращает '1.1'
. Фактически, он ищет все эквивалентные строковые представления (те, которые хранятся с одним и тем же базовым значением float) и возвращает кратчайшее представление.
Новый алгоритм имеет тенденцию выделять более чистые представления, когда это возможно, но не меняет базовые значения. Таким образом, все еще имеет место 1.1 + 2.2 != 3.3
, хотя представления могут предложить другое.
Новый алгоритм зависит от некоторых функций в реализации с плавающей запятой. Если требуемые функции не найдены, старый алгоритм будет по-прежнему использоваться. Кроме того, протоколы расписания текста обеспечивают кросс-платформенную переносимость, используя старый алгоритм.
Потому что это притворство. '>>> '{: .30f}'. Format (1./10)' ''0.100000000000000005551115123126'' –
Связано: [Почему str (float) возвращает больше цифр в Python 3, чем Python 2?] (Http : //stackoverflow.com/questions/25898733/why-does-strfloat-return-more-digits-in-python-3-than-python-2) –