2016-04-13 9 views
6

При работе с точностью поплавка я наткнулся на странный факт. Почему python печатает только целую часть при форматировании с "%.f". Я желаю знать механизм позади этогоТочность поплавка Python без целочисленной точности после десятичной точки

>>> a = float(2.12345) 
>>> a 
2.12345 
>>> print "%.2f" % a 
2.12 
>>> print "%.1f" % a 
2.1 
>>> print "%f" % a 
2.123450 
>>> print "%.f" % a 
2     #why? 

Заранее спасибо за объяснение :)

+1

Поскольку '«% .f»' так же, как '» % .0f "'? – Selcuk

+1

По той же причине, что '1.0' является таким же, как' 1.', вероятно. – TigerhawkT3

+0

Это, по-видимому, неопределенное поведение. Необязательная точность [указана как «.» (Точка), за которой следует точность] (https://docs.python.org/2/library/stdtypes.HTML # строка форматирования-операции). В документации по мини-языку спецификации формата (https://docs.python.org/2/library/string.html#format-specification-mini-language) аналогично требуется аргумент для точности. Поскольку 'int()' возвращает 0, он кажется разумным по умолчанию, но неопределенное поведение означает именно это. – Chris

ответ

4

Это было так ever since % formatting was added back in 1993; если за . не следует десятичное число, то precision is taken as zero.

Это недокументированная, но согласуется с printf, который % форматирование в Python был вдохновлен:

(необязательно) . с последующим целым числом или * или ни что определяет точность преобразования. В случае, когда используется *, точность указана дополнительным аргументом типа int. Если значение этого аргумента отрицательное, оно игнорируется. Если ни число, ни * не используются, точность принимается равной нулю.

Интересно, что еще одна недокументированная особенность также вдохновлен printf, что вы можете использовать * в точности, как и выше:

>>> "%6.*f" % (2, 1.234) 
' 1.23' 
+0

Ваш ответ кажется логичным для меня. Но мне интересно, почему формат строки вызывает ошибку значения, упомянутую srowland в его ответе? –

+2

@HiteshPaul 'string.format' - это более поздний API (представленный в PEP 3101), поэтому его можно было строго соответствовать спецификации; недокументированное поведение '%' не может быть удалено без нарушения обратной совместимости. – ecatmur

+0

@HiteshPaul См. Мой ответ ниже :) –

1

Документов для точности here не говоря уже по умолчанию, если точность пропущена. Я могу только предположить, что это работает именно так, потому что это так!

Документы предоставляют точность по умолчанию для% f как 6 в формате мини-языка спецификации here. Возможно, указав точность с помощью. а затем, опуская целочисленное значение, интерпретатор предполагает, что он должен быть равен нулю?

Это может даже по-разному вести себя на разных переводчиках. Интересно найти все равно :).

Интересно, что с помощью str.format бросает хороший ValueError в моем 2.7 переводчика:

>>> f = 234.12345676 
>>> "{:.f}".format(f) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: Format specifier missing precision 
+0

Кажется странным, хотя python вызывает ValueError для строкового формата, а для формата «%» - нет. –

+0

Полностью согласен с вами :). Я предполагаю, что формат имеет более строгую реализацию по этому вопросу. – srowland

+0

Значит ли это, что внутренняя реализация отличается для формата строки и% формата? –

1

Оператор % имеет следующее поведение, как вы наблюдали:

>>> "%.f" % 1.23 
'1' 

Парсер проходит через строку формата, с точностью undefined (-1) by default. Когда он достигает ., точность will be set to 0. Аргументы будут переданы в helper function formatfloat, который использует точность по умолчанию 6, если не задана точность, и не используется ..

Интересно отметить, что str.format() будет на самом деле throw an exception в этом случае, вероятно, для облегчения реализации и не позволяя людей полагаться на неустановленном поведении:

>>> "{:.f}".format(1.23) 
Traceback (most recent call last): 
    File "<ipython-input-6-677ba2e4a680>", line 1, in <module> 
    "{:.f}".format(1.23) 
ValueError: Format specifier missing precision 
Смежные вопросы