Преобразование Python float в Decimal
Python Decimal не поддерживает построение из float; он ожидает, что вам сначала нужно преобразовать float в строку.
Это очень неудобно, так как стандартные строковые форматеры для float требуют указания количества десятичных знаков, а не значимых мест. Поэтому, если у вас есть число, которое может иметь до 15 знаков после запятой, вам нужно отформатировать как десятичное (""%.15f " % my_float), который даст вам мусор на 15-м десятичном месте, если у вас также есть любые значимые цифры до десятичного знака.
может ли кто-нибудь предложить хороший способ преобразования из float в Decimal с сохранением значения по мере ввода пользователем, возможно, ограничивая количество значимых цифр, которые могут быть поддержаны?
7 ответов
Python
"%.15g" % f
"%.15g" % f
или в Python 3.0:
format(f, ".15g")
Python 2.7+, 3.2+
просто передайте поплавок Decimal
конструктор напрямую, вот так:
from decimal import Decimal
Decimal(f)
Вы сказали в своем вопросе:
может кто-нибудь предложить хороший способ преобразование из float в Decimal сохранение значения, как пользователь имеет вошел
но каждый раз, когда пользователь вводит значение, оно вводится как строка, а не как float. Вы превращаете его в какой-то поплавок. Преобразуйте его в десятичное число напрямую, и точность не будет потеряна.
Я предлагаю это
>>> a = 2.111111
>>> a
2.1111110000000002
>>> str(a)
'2.111111'
>>> decimal.Decimal(str(a))
Decimal('2.111111')
Python поддерживает десятичное создание из float. Сначала вы просто бросаете его как струну. Но потеря точности не происходит при преобразовании строки. Поплавок, который вы конвертируете, не имеет такой точности в первую очередь. (В противном случае вам не понадобится Decimal)
Я думаю, что путаница здесь в том, что мы можем создавать плавающие литералы в десятичном формате, но как только интерпретатор потребляет этот литерал, внутреннее представление становится плавающим номер точки.
"официальное" строковое представление float задается встроенным repr ():
>>> repr(1.5)
'1.5'
>>> repr(12345.678901234567890123456789)
'12345.678901234567'
вы можете использовать repr() вместо форматированной строки, результат не будет содержать ненужного мусора.
когда вы говорите "сохранение значения, введенного пользователем", почему бы просто не сохранить введенное пользователем значение в виде строки и передать его конструктору Decimal?
"правильный" способ сделать это было зафиксировано в 1990 году Стил и Уайт и PLDI Клингер в 1990 документы.
вы также можете посмотреть на этой Итак, обсуждение Python Decimal, включая мое предложение попробовать использовать что-то вроде фрап рационализировать поплавок.