Is there a way to get the ceil of a high precision Decimal in python?
>>> import decimal;
>>> decimal.Decimal(800000000000000000001)/100000000000000000000
Decimal('8.00000000000000000001')
>>> math.ceil(decimal.Decimal(800000000000000000001)/100000000000000000000)
8.0
math rounds the value and returns non precise value
The most direct way to take the ceiling of a Decimal instance x
is to use x.to_integral_exact(rounding=ROUND_CEILING)
. There's no need to mess with the context here. Note that this sets the Inexact
and Rounded
flags where appropriate; if you don't want the flags touched, use x.to_integral_value(rounding=ROUND_CEILING)
instead. Example:
>>> from decimal import Decimal, ROUND_CEILING
>>> x = Decimal('-123.456')
>>> x.to_integral_exact(rounding=ROUND_CEILING)
Decimal('-123')
Unlike most of the Decimal methods, the to_integral_exact
and to_integral_value
methods aren't affected by the precision of the current context, so you don't have to worry about changing precision:
>>> from decimal import getcontext
>>> getcontext().prec = 2
>>> x.to_integral_exact(rounding=ROUND_CEILING)
Decimal('-123')
By the way, in Python 3.x, math.ceil
works exactly as you want it to, except that it returns an int
rather than a Decimal
instance. That works because math.ceil
is overloadable for custom types in Python 3. In Python 2, math.ceil
simply converts the Decimal
instance to a float
first, potentially losing information in the process, so you can end up with incorrect results.
x = decimal.Decimal('8.00000000000000000000001')
with decimal.localcontext() as ctx:
ctx.prec=100000000000000000
ctx.rounding=decimal.ROUND_CEILING
y = x.to_integral_exact()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With