# convert user input to Decimal objects using eval()?

4 views

### Julian Hernandez Gomez

Mar 28, 2005, 12:03:24 PM3/28/05
to pytho...@python.org
Hi !

This is maybe a silly question, but...

is there a "easy way" to make eval() convert all floating numbers to Decimal
objects and return a Decimal?

for example:

eval('1.00000001+0.1111111') --> convert each number to a Decimal object,
perform the sum and obtain a Decimal object as a result?

maybe a parser is needed, but eval() already do the job, but I need the
precision that Decimal offers for numerical applications.

--
Julián

### Swaroop C H

Mar 28, 2005, 4:05:40 PM3/28/05
to Julian Hernandez Gomez, pytho...@python.org
On Mon, 28 Mar 2005 12:03:24 -0500, Julian Hernandez Gomez
<jhern...@pragma.com.co> wrote:
> is there a "easy way" to make eval() convert all floating numbers to Decimal
> objects and return a Decimal?
> eval('1.00000001+0.1111111') --> convert each number to a Decimal object,
> perform the sum and obtain a Decimal object as a result?
> maybe a parser is needed, but eval() already do the job, but I need the
> precision that Decimal offers for numerical applications.

If you need the precision, why are you using strings instead of the
numbers directly?

Also, why not simply use Decimal('1.0000000') + Decimal('0.1111111') ?

--
Swaroop C H
Blog: http://www.swaroopch.info
Book: http://www.byteofpython.info

### Raymond Hettinger

Mar 29, 2005, 3:04:18 AM3/29/05
to
[Julian Hernandez Gomez]

> This is maybe a silly question, but...
>
> is there a "easy way" to make eval() convert all floating
> numbers to Decimal objects and return a Decimal?

from decimal import Decimal
import re

number = re.compile(r"((\b|(?=\W))(\d+(\.\d*)?|\.\d+)([eE][+-]?\d{1,3})?)")
deciexpr = lambda s: number.sub(r"Decimal('\1')", s)

for s in ('1.00000001+0.1111111',
'+21.3e-5*85-.1234/81.6',
'1.0/7'):
print '%s\n --> %r' % (s, eval(s))
s = deciexpr(s)
print '%s\n --> %r\n' % (s, eval(s))

"""
1.00000001+0.1111111
--> 1.11111111
Decimal('1.00000001')+Decimal('0.1111111')
--> Decimal("1.11111111")

+21.3e-5*85-.1234/81.6
--> 0.016592745098039215
+Decimal('21.3e-5')*Decimal('85')-Decimal('.1234')/Decimal('81.6')
--> Decimal("0.01659274509803921568627450980")

1.0/7
--> 0.14285714285714285
Decimal('1.0')/Decimal('7')
--> Decimal("0.1428571428571428571428571429")

"""

Raymond Hettinger

### Julian Hernandez Gomez

Mar 29, 2005, 9:22:15 AM3/29/05
to pytho...@python.org
On Tuesday 29 March 2005 03:04, Raymond Hettinger wrote:
> from decimal import Decimal
> import re
>
> number = re.compile(r"((\b|(?=\W))(\d+(\.\d*)?|\.\d+)([eE][+-]?\d{1,3})?)")
> deciexpr = lambda s: number.sub(r"Decimal('\1')", s)
>
> for s in ('1.00000001+0.1111111',
>    '+21.3e-5*85-.1234/81.6',
>    '1.0/7'):
>     print '%s\n  --> %r' % (s, eval(s))
>     s = deciexpr(s)
>     print '%s\n  --> %r\n' % (s, eval(s))

Wow!

Thank you so much!!!

now I can do my simple math function evaluator much more reliable !

Thanks again!

--
Julián

### Terry Reedy

Mar 29, 2005, 8:58:36 PM3/29/05
to pytho...@python.org

"Raymond Hettinger" <vze4...@verizon.net> wrote in message
news:6_72e.50077\$u76.2569@trndny08...

This is less obvious and more useful, to me, than some of the recipies in
the new Cookbook.

TJR

### Raymond Hettinger

Mar 30, 2005, 3:36:10 AM3/30/05
to
> > [Julian Hernandez Gomez]

> >> is there a "easy way" to make eval() convert all floating
> >> numbers to Decimal objects and return a Decimal?

[Raymond Hettinger]

> > from decimal import Decimal
> > import re
> >
> > number =
> > re.compile(r"((\b|(?=\W))(\d+(\.\d*)?|\.\d+)([eE][+-]?\d{1,3})?)")
> > deciexpr = lambda s: number.sub(r"Decimal('\1')", s)

[Terry Reedy]

> This is less obvious and more useful, to me, than some of the recipies in
> the new Cookbook.

Okay, we can fix that. I've cleaned it up a bit and posted it on ASPN with
references, docs, and a doctest:

Raymond