Python плавает до десятичного преобразования

Python Decimal не поддерживает построение из float; он ожидает, что вам нужно сначала преобразовать float в строку.

Это очень неудобно, поскольку стандартные форматирования строк для float требуют, чтобы вы указывали число десятичных знаков, а не значительных мест. Поэтому, если у вас есть число, которое может содержать до 15 знаков после запятой, вам нужно отформатировать как десятичный ( "%. 15f" % my_float), что даст вам мусор в 15-м десятичном разряде, если у вас также есть какие-либо значащие цифры перед десятичное.

Может ли кто-нибудь предложить хороший способ конвертировать из float в значение сохранения десятичного значения, как только пользователь ввел, возможно, ограничение числа значимых цифр, которые могут поддерживаться?

Ответ 1

Python < 2.7

"%.15g" % f

Или в Python 3.0:

format(f, ".15g")

Python 2.7+, 3.2 +

Просто передайте конструктор float в конструктор Decimal.

Ответ 2

Вы сказали в своем вопросе:

Может кто-нибудь предложить хороший способ конвертировать из float в десятичный сохраняющее значение, поскольку пользователь имеет вошли

Но каждый раз, когда пользователь вводит значение, он вводится как строка, а не как float. Вы конвертируете его в поплавок. Вместо этого конвертируйте его в десятичный код и не потеряйте точность.

Ответ 3

Я предлагаю это

>>> a = 2.111111
>>> a
2.1111110000000002
>>> str(a)
'2.111111'
>>> decimal.Decimal(str(a))
Decimal('2.111111')

Ответ 4

Python поддерживает создание десятичных чисел из поплавка. Сначала вы просто набросаете его как строку. Но потери точности не происходят при преобразовании строк. Первое, что вы делаете, - это то, что вы конвертируете. (В противном случае вам не понадобится Decimal)

Я думаю, что путаница здесь заключается в том, что мы можем создавать float-литералы в десятичном формате, но как только интерпретатор потребляет этот литерал, внутреннее представление становится числом с плавающей запятой.

Ответ 5

Когда вы произносите "сохранение значения по мере ввода пользователя", почему бы просто не сохранить введенное пользователем значение в виде строки и передать это конструктору Decimal?

Ответ 6

"Официальное" строковое представление поплавка задается встроенной функцией repr():

>>> repr(1.5)
'1.5'
>>> repr(12345.678901234567890123456789)
'12345.678901234567'

Вы можете использовать функцию repr() вместо форматированной строки, результат не будет содержать лишний мусор.

Ответ 7

"Правильный" способ сделать это был задокументирован в 1990 году Steele and White and Clinger PLDI 1990.

Вы также можете посмотреть это SO обсуждение Python Decimal, включая мое предложение попробовать что-то вроде frap, чтобы рационализировать float.