2

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!

5
  • Is it okay if you can hold this as a string??? Commented Nov 14, 2013 at 14:58
  • No problem but I need to define a class! Commented Nov 14, 2013 at 15:03
  • Is there some reason that decimal.Decimal doesn't work for you? Commented Nov 14, 2013 at 15:27
  • See my answer that will give you string representation of value based on numerator and denominator and precision which can be used for any fractional number not just for pi. Commented Nov 14, 2013 at 15:38
  • related: Gauss-Legendre Algorithm in python Commented Dec 1, 2013 at 17:25

4 Answers 4

6

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. 
Sign up to request clarification or add additional context in comments.

Comments

1

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.

7 Comments

If I use something like x+dc(2) the program will represent this number: Decimal('5.141592653589793238462643383')
Yes, x is a normal object of type Decimal and it has arbitrary precision. Your issue was the limited precision of the number you've passed as a parameter to its constructor.
So what I have to do? I have this large decimal number and I want add some number like 2.
Treat it like any other number, x+=2. Read the Decimal docs
As I said before the other decimal numbers will disappear and python shows Decimal('5.141592653589793238462643383')
|
0

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.

Comments

0

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' 

2 Comments

@rogaos: My point was not to identify the difference between actual pi and 22/7 which I know there is a difference but just to assist the OP in finding the way to store the values of terms such as 22/7 (close to pi) in a way he wants.
I downvoted because I found that point very unclear; pi is decidedly not a fractional number. if you edit your post accordingly, I'll rescind. Note that if he wants 1000 (correct) decimal digits, he might need a 1000 digit numerator, which doesn't seem to be a sustainable technique. And doesn't the Fractions module already do this?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.