No subject

jholg at gmx.de jholg at gmx.de
Tue Dec 22 11:33:33 EST 2009


Hi,

I need to convert Python decimal.Decimal data to the XMLSchema xs:decimal datatype. This is reasonably straightforward, but there are some corner cases.

In particular, xs:decimal does not allow exponential notation like:

>>> print Decimal('0.00000000000000000023430000000837483727772')
2.3430000000837483727772E-19
>>>

Is there a convenient way to force a decimal.Decimal representation to not use exponential representation?

While I've seen this decimal FAQ entry:

Q. Some decimal values always print with exponential notation. Is there a way to get a non-exponential representation?

A. For some values, exponential notation is the only way to express the number of significant places in the coefficient. For example, expressing 5.0E+3 as 5000 keeps the value constant but cannot show the original’s two-place significance.

If an application does not care about tracking significance, it is easy to remove the exponent and trailing zeroes, losing significance, but keeping the value unchanged:

    >>> def remove_exponent(d):
    ...     return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()

    >>> remove_exponent(Decimal('5E+3'))
    Decimal('5000')

...this doesn't really apply to my usecase:

It does not work for "small" values:

remove_exponent(Decimal('0.00000000000000000023430000000837483727772'))
Decimal('2.3430000000837483727772E-19')
>>>

and it can lead to errors if the sheer number size can't be handled:

>>> d2 = Decimal('1e80')
>>> remove_exponent(d2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in remove_exponent
  File "/apps/prod/gcc/4.2.1/lib/python2.6/decimal.py", line 2308, in quantize
    'quantize result has too many digits for current context')
  File "/apps/prod/gcc/4.2.1/lib/python2.6/decimal.py", line 3680, in _raise_error
    raise error(explanation)
decimal.InvalidOperation: quantize result has too many digits for current context
>>>

I could easily adapt this recipe:

http://code.activestate.com/recipes/358361/

which works on the string and basically removes exponential notation, moves the fraction '.'-dot and adds appropriate zeros.

Doesn't seem very lightweight, though.

Any obvious alternatives I'm missing?

Thanks,
Holger
-- 
Preisknaller: GMX DSL Flatrate für nur 16,99 Euro/mtl.!
http://portal.gmx.net/de/go/dsl02



More information about the Python-list mailing list