3

I am dealing with a bug where applying the str function to an instance of decimal.Decimal gives me the string '0E-1000'. I expected that str applied to a Decimal would always give me a string of the form -?[0-9]+(\.[0-9]+), which is what I want.

Firstly, if I understand correctly, the scientific notation '0E-1000' represents 0 x 10^-1000, i.e. zero. Why am I getting this particular representation of zero? Why not '0E-42', which is the same?

Secondly, I cannot manually construct a Decimal which reproduces this bug. The buggy Decimal instance comes from an external source. The expression str(Decimal(0)) evaluates to '0' in the REPL. How can I construct an instance d of Decimal for which str(d) evaluates to '0E-1000'?

EDIT: Thirdly, how can I convert an arbitrary Decimal instance to a string in, you know, decimal notation?

2
  • Where is this number coming from? Commented Feb 13, 2015 at 15:44
  • It's coming from a field in a Django model. The field is defined as models.DecimalField(max_digits=1000, decimal_places=1000, blank=True, null=True). Commented Feb 13, 2015 at 15:47

1 Answer 1

7

If you want to reproduce your decimal, just construct it from the string:

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

I believe the difference is the difference between 0 and 0.00000 (or in your case 1000 zeros), which is the accuracy. This could be significant in scientific situations, where rounding etc. is controlled by the precision of the operands. If you want to make printing consistent, use decimal.Decimal.normalize:

>>> d=decimal.Decimal("0E-1000")
>>> d
Decimal('0E-1000')
>>> d.normalize()
Decimal('0')
>>> str(d.normalize())
'0'
Sign up to request clarification or add additional context in comments.

2 Comments

Ahh, normalize helps! Weird. I would expect all normalized Decimals to be normalized automatically. It's quite strange to have to deal with multiple equivalent representations of the same number in the same datatype. (I also have to get my head around this "precision" stuff, which is specified by some hideous global context ...)
decimal.localcontext may keep the global velociraptors away. Just pushes indentation further towards the 80 char PEP8 mark instead...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.