Python Decimal to string создает странную научную нотацию

Я имею дело с ошибкой, когда применение функции str к экземпляру decimal.Decimal дает мне строку '0E-1000'. Я ожидал, что str, примененный к Decimal, всегда будет давать мне строку в форме -?[0-9]+(\.[0-9]+), что мне и нужно.

Во-первых, если я правильно понимаю, научная запись '0E-1000' представляет собой 0 x 10^-1000, то есть ноль. Почему я получаю именно это представление нуля? Почему не '0E-42', что то же самое?

Во-вторых, я не могу вручную создать Decimal, воспроизводящий эту ошибку. Экземпляр с ошибками Decimal поступает из внешнего источника. Выражение str(Decimal(0)) оценивается как '0' в REPL. Как я могу создать экземпляр d из Decimal, для которого str(d) оценивается как '0E-1000'?

РЕДАКТИРОВАТЬ: В-третьих, как я могу преобразовать произвольный экземпляр Decimal в строку, как вы знаете, в десятичной нотации?


person jameshfisher    schedule 13.02.2015    source источник
comment
Откуда это число?   -  person lurker    schedule 13.02.2015
comment
Это исходит из поля в модели Django. Поле определено как models.DecimalField(max_digits=1000, decimal_places=1000, blank=True, null=True).   -  person jameshfisher    schedule 13.02.2015


Ответы (1)


Если вы хотите воспроизвести свое десятичное число, просто создайте его из строки:

>>> d=decimal.Decimal("0E-1000")
>>> str(d)
'0E-1000'

Я считаю, что разница - это разница между 0 и 0.00000 (или в вашем случае 1000 нулей), что является точностью. Это может иметь значение в научных ситуациях, когда округление и т. д. контролируется точностью операндов. Если вы хотите сделать печать последовательной, используйте decimal.Decimal.normalize:

>>> d=decimal.Decimal("0E-1000")
>>> d
Decimal('0E-1000')
>>> d.normalize()
Decimal('0')
>>> str(d.normalize())
'0'
person matsjoyce    schedule 13.02.2015
comment
Ааа, normalize помогает! Странный. Я бы ожидал, что все нормализованные десятичные числа будут нормализованы автоматически. Довольно странно иметь дело с несколькими эквивалентными представлениями одного и того же числа в одном и том же типе данных. (Мне также нужно разобраться с этой точностью, которая определяется каким-то отвратительным глобальным контекстом...) - person jameshfisher; 13.02.2015
comment
decimal.localcontext может сохранить глобальный велоцирапторов подальше. Вместо этого просто сдвигает отступ дальше к 80-символьной отметке PEP8... - person matsjoyce; 13.02.2015