tonix
tonix

Reputation: 6939

Is there a way to inhibit rounding in python?

is there a way to inhibit python rounding, e.g.:

>>> getcontext().prec = 11; print (Decimal(1.1237836550999999999)*10**10)
11237836551

I need to show the first 10 decimal places of the decimal number, so actually I need 11237836550 as output and I do not need that rounding on the last digit (in this case that 0 rounded to a 1).

Sometimes I can just increase the precision (not in this case) and then perform the calculation safely, like this:

>>> getcontext().prec = 14; print (Decimal(1.12378365509978)*10**10)
11237836550.998

But suppose that you are not aware of the decimal part of the number after that '0', e.g. it could be 1.1237836550999999999999999999999999... and so on, and then you cannot rely upon this 'workaround'.

So, is there a way to tell python, "for this calculation, I don't want any rounding to be performed, actually I want that you just return me the needed number of decimals (10 in this example), and throw away anything else after it"?

I took a look here Truncating floats in Python, but basically what I need is not a string of a truncated float, but another decimal to use to perform calculations upon. Furthermore, the trunc function of the accepted answer in the post I linked will not work in this case, cause the Decimal will be rounded just before it will be passed to the function's 'f' argument:

>>> def trunc(f, n):
...     '''Truncates/pads a float f to n decimal places without rounding'''
...     return ('%.*f' % (n + 1, f))[:-1]
... 
>>> trunc(Decimal(1.12378365509978), 10)
'1.1237836551' # and not 1.1237836550 as needed

How can I accomplish that?

Upvotes: 0

Views: 711

Answers (2)

dmg
dmg

Reputation: 7706

You problem is not Decimal. It's float. Namely:

>>> 1.1237836550999999999
1.1237836551

But if you do:

>>> int(Decimal("1.1237836550999999999")*10**10)
11237836550

You are good to go. Use strings when initializing decimals with higher precision.

Upvotes: 7

dragon2fly
dragon2fly

Reputation: 2419

Is this what you are finding:

from decimal import *

getcontext().prec = 103

def precision(context, prec=100):

    return Decimal(context).quantize(Decimal('.'+'0'*(prec-1)+'1'), rounding=ROUND_DOWN)

print precision(Decimal(10).log10() / Decimal(2).log10())

Output:

3.3219280948873623478703194294893901758648313930245806120547563958159347766086252158501397433593701550

Upvotes: 2

Related Questions