Python с плавающей точкой в ​​десятичное преобразование - PullRequest
46 голосов
/ 25 ноября 2008

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

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

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

Ответы [ 7 ]

49 голосов
/ 25 ноября 2008

Python <2,7 </h3> "%.15g" % f Или в Python 3.0: format(f, ".15g") Python 2.7+, 3.2 +

Просто передайте float в Decimal конструктор напрямую, например:

from decimal import Decimal
Decimal(f)
23 голосов
/ 25 ноября 2008

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

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

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

10 голосов
/ 07 декабря 2011

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

>>> a = 2.111111
>>> a
2.1111110000000002
>>> str(a)
'2.111111'
>>> decimal.Decimal(str(a))
Decimal('2.111111')
4 голосов
/ 05 декабря 2008

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

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

3 голосов
/ 25 ноября 2008

«Официальное» строковое представление типа float задается встроенным в repr ():

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

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

2 голосов
/ 25 ноября 2008

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

0 голосов
/ 25 ноября 2008

«Правильный» способ сделать это был задокументирован в 1990 году Стилом и Уайтом и PLDI Clinger 1990 документы.

Вы также можете посмотреть это ТАКОЕ обсуждение Python Decimal, включая мое предложение попробовать использовать что-то вроде frap для рационализации числа с плавающей запятой.

...