преобразование из числа с плавающей точкой в ​​десятичное в Python-2.6: как это сделать и почему они этого не сделали - PullRequest
14 голосов
/ 03 ноября 2011

Прямое преобразование из float в Decimal было реализовано в python-2.7, как в конструкторе Decimal, так и с использованием метода класса Decimal.from_float ().

Вместо Python-2.6 выдается ошибка TypeError, предлагающая сначала преобразовать в строку:

TypeError: Cannot convert float to Decimal.  First convert the float to a string

поэтому мой обычный обходной путь таков:

if sys.version_info < (2, 7):
    Decimal.from_float = classmethod(lambda cls, x: cls(str(x)))

Это просто литературный перевод сообщения об ошибке - и я просто не беспокоюсь о его реализации в конструкторе.

Если это так просто, почему они не реализовали это в первую очередь вместо того, чтобы сказать пользователю сделать это в TypeError?Это лучший доступный метод (и, более того, тот, который используется в python-2.7 и новее?)

Ответы [ 3 ]

11 голосов
/ 04 ноября 2011

Ваш обходной путь - не RightWayToDoIt (tm), потому что он теряет информацию.Способ конвертации без потерь показан в рецепте float_to_decimal(), указанном в Десятичном разделе часто задаваемых вопросов .

. Причина, по которой мы не включили Decimal.from_float в Python 2.6, заключается в том, что мыконсервативно вводить непреднамеренные взаимодействия между двоичными и десятичными числами.В Python 2.7 все это было сработано, и вы можете просто написать Decimal(f), где f - двоичное число с плавающей запятой.

Кроме небольшого неудобства в 2.6, я надеюсь, вам понравится модуль Decimal

4 голосов
/ 03 ноября 2011

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

Примечание Decimal.from_float(0.1) отличается от Decimal('0.1'). Поскольку 0.1 не является точно представимым в двоичной с плавающей запятой, значение сохраняется как ближайшее представимое значение, которое 0x1.999999999999ap-4. Это эквивалентное значение в десятичном виде 0.1000000000000000055511151231257827021181583404541015625.

Если вы преобразуете в строку, вы можете контролировать точность, которую хотите использовать, чтобы вы могли получить точное преобразование в Decimal.

Новый метод был представлен в Python 2.7, поэтому его нет в 2.6. Новые функции не переносятся в более старые версии.

0 голосов
/ 03 ноября 2011

В соответствии с 2.7 Что нового документация (выделение добавлено)

Преобразования между числами с плавающей точкой и строками теперь правильно округлено на большинстве платформ. Эти преобразования происходят во многих разные места: str () на числах с плавающей точкой и комплексных числах; поплавок и сложные конструкторы; числовое форматирование; сериализация и десериализацию поплавков и комплексных чисел с использованием маршала, маринада и JSON-модули; парсинг float и мнимых литералов в коде Python; и десятичное преобразование в число с плавающей запятой .

Так что, хотя они могли бы сделать это до 2.7, они, очевидно, не чувствовали себя комфортно, делая это с существующими проблемами округления.

...