How to define a decimal class holding 1000 digits in python?

偶尔善良 提交于 2019-11-26 14:53:11

问题


I need a class holding 1000 decimal digits to calculate something like pi number in a series. Taking time is not important. How can I define __add__ & ... functions to do this? For example I need a value can hold this number: 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113

:))

This number using decimal.Decimal shows like this:

from decimal import Decimal as dc
>>> x=dc(3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113)
>>> x
Decimal('3.141592653589793115997963468544185161590576171875')

But I need a new class holding all DIGITS and I can use adding, dividing and ... functions in it like 2+1 and pi number is an example of that and exactly I don't need to calculate pi number I wanted to calculate extra large decimal numbers!


回答1:


You have to set a context with 1000 decimal digits:

context = decimal.Context(prec=1000)
decimal.setcontext(context)

From now on computations will use 1000 digits precision.

Example:

>>> decimal.setcontext(decimal.Context(prec=1000))
>>> pi = decimal.Decimal('3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113')
>>> pi
Decimal('3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113')
>>> pi + 2
Decimal('5.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113')

Note that:

  • You have to use strings to initialize the Decimal because if you use a float the interpreter will have to truncate it first. (also I believe only the most recent versions of decimal accept a float argument. In older versions you had to use Decimal.from_float instead).
  • The decimal digits are preserved during calculations.

You can also use the context locally via the localcontext contextmanager:

context = decimal.Context(prec=1000)

with decimal.localcontext(context):
    # here decimal uses 1000 digits for computations
    pass

# here the default context is restored.



回答2:


You made the mistake of initialising the Decimal object with a double which can't represent your big number.

So instead of saying:

x=dc(3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113)

...which has exactly the same effect as:

x=dc(3.1415926535897932384626433832795)

...initialise from a string:

x=dc('3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113')

and you'll get the expected result with full precision.




回答3:


My try. Might NOT be very good.

class pi:
    def __init__(self):
        self.pi_digits = ['1', '4', '1', '5', '9', '2', '6'] # pi = 3.1415926
    def __repr__(self):
        return '3.'+''.join(self.pi_digits)
    def add(self, digit):
        digit = str(digit)
        if digit.isdigit():
            self.pi_digits.append(digit)
        else:
            raise TypeError

my_pi = pi()
my_pi.add(3)
my_pi.add(5)
print (my_pi)

Output

3.141592635

PS - This is just to give you a rough idea of how you might go about doing things.




回答4:


This function will give you string of value based on numerator (numer) and denominator (deno) and precision which can be used for any fractional number not just for pi. For pi, you can just use 22/7 and any precision you want.

def pi_accur(numer,deno,precision):
    pi_holder=[]
    while (precision>=1):
        pi_holder.append(int(numer/deno))
        numer=10*(numer%deno)
        precision=precision-1

    new_val=str(pi_holder[0])+'.'
    for i in pi_holder[1:]:
        new_val=new_val+str(i)
    return new_val

>>> pi_accur(22,7,9)
     '3.14285714'

>>>pi_accur(22,7,15)
   '3.14285714285714'


来源:https://stackoverflow.com/questions/19980840/how-to-define-a-decimal-class-holding-1000-digits-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!