Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > how to convert from Decimal('1.23456789') to Decimal('1.234')

Reply
Thread Tools

how to convert from Decimal('1.23456789') to Decimal('1.234')

 
 
valpa
Guest
Posts: n/a
 
      03-23-2009
I only need the 3 digits after '.'

Is there any way other than converting from/to string?
 
Reply With Quote
 
 
 
 
alex23
Guest
Posts: n/a
 
      03-23-2009
On Mar 23, 4:40*pm, valpa <(E-Mail Removed)> wrote:
> I only need the 3 digits after '.'
>
> Is there any way other than converting from/to string?


I'm not sure if this is the canonical way but it works:

>>> d = Decimal('1.23456789')
>>> three_places = Decimal('0.001') # or anything that has the exponent depth you want
>>> d.quantize(three_places, 'ROUND_DOWN')

Decimal('1.234')
 
Reply With Quote
 
 
 
 
Hyunchul Kim
Guest
Posts: n/a
 
      03-23-2009
In that case, I usually use

# when rounding is proper,
s = '1.23456789'
print round(float(s))

or

# when cut out is proper,
from math import floor
print floor(float(s)*1000)/1000

Hyunchul

valpa wrote:
> I only need the 3 digits after '.'
>
> Is there any way other than converting from/to string?
> --
> http://mail.python.org/mailman/listinfo/python-list
>
>
>


 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      03-23-2009
On Sun, 22 Mar 2009 23:40:38 -0700, valpa wrote:

> I only need the 3 digits after '.'
>
> Is there any way other than converting from/to string?


You should Read the Fine Manual:

http://docs.python.org/library/decimal.html


[quote]
The quantize() method rounds a number to a fixed exponent. This method is
useful for monetary applications that often round results to a fixed
number of places:

>>> Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_DOWN)

Decimal('7.32')
>>> Decimal('7.325').quantize(Decimal('1.'), rounding=ROUND_UP)

Decimal('8')

[end quote]

In my opinion, that's hideously ugly, but you can create a helper
function very easily:

def round(dec, places, rounding=decimal.ROUND_HALF_UP):
return dec.quantize(decimal.Decimal(str(10**-places)), rounding)



--
Steven
 
Reply With Quote
 
Mark Dickinson
Guest
Posts: n/a
 
      03-23-2009
On Mar 23, 7:01*am, alex23 <(E-Mail Removed)> wrote:
> On Mar 23, 4:40*pm, valpa <(E-Mail Removed)> wrote:
>
> > I only need the 3 digits after '.'

>
> > Is there any way other than converting from/to string?

>
> I'm not sure if this is the canonical way but it works:
>
> >>> d = Decimal('1.23456789')
> >>> three_places = Decimal('0.001') # or anything that has the exponent depth you want
> >>> d.quantize(three_places, 'ROUND_DOWN')

>
> Decimal('1.234')


Yes, that's the official 'right way'. There's
also a _rescale method that does this:

>>> Decimal('1.23456789')._rescale(-3, 'ROUND_HALF_EVEN')

Decimal('1.235')

.... but as the leading underscore indicates, it's
private and undocumented, so you shouldn't rely on it
not to change or disappear in a future version.

The two methods are subtly different, in that the
quantize method respects the current context, while
the _rescale method ignores it. For example:

>>> getcontext().prec = 3
>>> Decimal('1.23456789').quantize(Decimal('0.001'))

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/dickinsm/python_source/trunk/Lib/decimal.py", line
2364, in quantize
'quantize result has too many digits for current context')
File "/Users/dickinsm/python_source/trunk/Lib/decimal.py", line
3735, in _raise_error
raise error(explanation)
decimal.InvalidOperation: quantize result has too many digits for
current context
>>> Decimal('1.23456789')._rescale(-3, 'ROUND_DOWN')

Decimal('1.234')
[61114 refs]

Mark
 
Reply With Quote
 
Mensanator
Guest
Posts: n/a
 
      03-23-2009
On Mar 23, 2:24�am, Steven D'Aprano
<(E-Mail Removed)> wrote:
> On Sun, 22 Mar 2009 23:40:38 -0700, valpa wrote:
> > I only need the 3 digits after '.'

>
> > Is there any way other than converting from/to string?

>
> You should Read the Fine Manual:
>
> http://docs.python.org/library/decimal.html
>
> [quote]
> The quantize() method rounds a number to a fixed exponent. This method is
> useful for monetary applications that often round results to a fixed
> number of places:
>
> >>> Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_DOWN)

> Decimal('7.32')
> >>> Decimal('7.325').quantize(Decimal('1.'), rounding=ROUND_UP)

>
> Decimal('8')
>
> [end quote]
>
> In my opinion, that's hideously ugly,


In looking at this for the first time, it struck
me as funny why the first argument to quantize
even requires a number since you can pass a
Conext as an argument. But if you do, precision
is ignored. Quantize isn't the way to do that.

> but you can create a helper
> function very easily:
>
> def round(dec, places, rounding=decimal.ROUND_HALF_UP):
> � � return dec.quantize(decimal.Decimal(str(10**-places)), rounding)


Still ugly. I would do this:

>>> a = Decimal('1.23456789')


>>> for i in xrange(1,6):

print Context.create_decimal(Context(i,ROUND_DOWN),a)
1
1.2
1.23
1.234
1.2345

>>> print a

1.23456789


>
> --
> Steven


 
Reply With Quote
 
Mark Dickinson
Guest
Posts: n/a
 
      03-23-2009
On Mar 23, 6:40*am, valpa <(E-Mail Removed)> wrote:
> I only need the 3 digits after '.'
>
> Is there any way other than converting from/to string?


And in Python 3.0, just use the built-in round function:

>>> from decimal import Decimal
>>> round(Decimal('1.23456789'), 3)

Decimal('1.235')

This uses the rounding specified by the context, so if
you want a rounding mode other than the default
ROUND_HALF_EVEN, just set the context rounding
appropriately:

>>> from decimal import getcontext, ROUND_DOWN
>>> getcontext().rounding = ROUND_DOWN
>>> round(Decimal('1.23456789'), 3)

Decimal('1.234')

Mark
 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      03-23-2009
On Mon, 23 Mar 2009 01:45:53 -0700, Mensanator wrote:

>> but you can create a helper
>> function very easily:
>>
>> def round(dec, places, rounding=decimal.ROUND_HALF_UP): � � return
>> dec.quantize(decimal.Decimal(str(10**-places)), rounding)

>
> Still ugly. I would do this:
>
>>>> a = Decimal('1.23456789')

>
>>>> for i in xrange(1,6):

> print Context.create_decimal(Context(i,ROUND_DOWN),a)


Well, that's hardly any less ugly.

And it also gives different results to my function: my function rounds to
<places> decimal places, yours to <i> digits. Very different things.


--
Steven
 
Reply With Quote
 
Mensanator
Guest
Posts: n/a
 
      03-23-2009
On Mar 23, 5:48*am, Steven D'Aprano <st...@REMOVE-THIS-
cybersource.com.au> wrote:
> On Mon, 23 Mar 2009 01:45:53 -0700, Mensanator wrote:
> >> but you can create a helper
> >> function very easily:

>
> >> def round(dec, places, rounding=decimal.ROUND_HALF_UP): return
> >> dec.quantize(decimal.Decimal(str(10**-places)), rounding)

>
> > Still ugly. I would do this:

>
> >>>> a = Decimal('1.23456789')

>
> >>>> for i in xrange(1,6):

> > * *print Context.create_decimal(Context(i,ROUND_DOWN),a)

>
> Well, that's hardly any less ugly.


I wouldn't say so since there are no strings attached. Didn't the
OP specifically ask for a solution that didn't involve strings?

>
> And it also gives different results to my function: my function rounds to
> <places> decimal places, yours to <i> digits. Very different things.


Yeah, I know all about that. I work in Environmental Remediation.
That's real science, where rounding to decimal places is strictly
forbidden, significant digits must be preserved. That means rounding
to digits. Do you know what kind of hoops I have to jump through to
get Access or Excel to round properly when doing unit conversion?

Surely you're not so maive that you think dividing by 1000 simply
moves
the decimal point three places?

>
> --
> Steven


 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      03-23-2009
On Mon, 23 Mar 2009 10:06:23 -0700, Mensanator wrote:

> On Mar 23, 5:48*am, Steven D'Aprano <st...@REMOVE-THIS-
> cybersource.com.au> wrote:
>> On Mon, 23 Mar 2009 01:45:53 -0700, Mensanator wrote:
>> >> but you can create a helper
>> >> function very easily:

>>
>> >> def round(dec, places, rounding=decimal.ROUND_HALF_UP): return
>> >> dec.quantize(decimal.Decimal(str(10**-places)), rounding)

>>
>> > Still ugly. I would do this:

>>
>> >>>> a = Decimal('1.23456789')

>>
>> >>>> for i in xrange(1,6):
>> > * *print Context.create_decimal(Context(i,ROUND_DOWN),a)

>>
>> Well, that's hardly any less ugly.

>
> I wouldn't say so since there are no strings attached. Didn't the OP
> specifically ask for a solution that didn't involve strings?


No, the OP asked for a solution that didn't involve converting the
decimal number to a string first.

Besides, I don't believe you can specify the rounding mode unless you use
strings *wink*

>>> type(ROUND_DOWN)

<type 'str'>



>> And it also gives different results to my function: my function rounds
>> to <places> decimal places, yours to <i> digits. Very different things.

>
> Yeah, I know all about that. I work in Environmental Remediation. That's
> real science, where rounding to decimal places is strictly forbidden,
> significant digits must be preserved. That means rounding to digits.


Okay, so in other words you solved your problem rather than the OP's
problem.


> Do
> you know what kind of hoops I have to jump through to get Access or
> Excel to round properly when doing unit conversion?


I feel your pain.


> Surely you're not so maive that you think dividing by 1000 simply moves
> the decimal point three places?


Of course it does, if you're using real numbers. If you're using floats,
no, not quite, there are rounding issues involved, and underflow.

I'm not sure why you raise this. Is this a general rant, or do you have a
specific criticism?


--
Steven
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
IsNumeric: Convert.ToInt32 vs. Convert.ToInt64 sck10 ASP .Net 4 09-03-2006 09:40 PM
To convert to J2SE 6 or not to convert, that is the question... Jaap Java 4 07-10-2006 09:03 AM
convert list of strings to set of regexes; convert list of strings to trie Klaus Neuner Python 7 07-26-2004 07:25 AM
Do I need to Convert with Convert.ToInt32(session("myNumber")) ? Andreas Klemt ASP .Net 1 07-23-2003 02:59 PM



Advertisments