For a part of my half-year school project I am trying to make a program to calculate pi to large precision. Now python (my preferred language) doesn't have that high precision, just like most other languages. What programming language would be good for my usage?
You can use the decimal module in Python for computing decimal numbers to high precision.
that is correct, but then my program that uses sqrt() or factorial or basically anything the program goes wrong after 15 decimals, the same amount i get when i dont use the module.
Jelte2357 wrote:
that is correct, but then my program that uses sqrt() goes wrong after 15 decimals, the same amount i get when i dont use the module.


Did you set the precision correctly? Also, how are you utilizing square roots to calculate pi?
I am using multiple different ways to calculate pi, including the earliest one (archimedes) and that one uses square roots. is used getcontext().prec=50 for my program, and the output is 3.14159265358979 [42262209880937007255852222442626952]. the text between [] is incorrect.
it sounds like you are using math.sqrt instead of Decimal.sqrt.
Example:
Code:
import decimal,math
decimal.getcontext().prec = 53
print(decimal.Decimal(math.sqrt(2)))
print(decimal.Decimal(2).sqrt())
outputs
Code:
1.4142135623730951454746218587388284504413604736328125
1.4142135623730950488016887242096980785696718753769481
the second one using Decimal.sqrt() being the expected output.
thank you logicaljoe, how would this work with powers and factorials? (sorry if I am asking easy/dumb questions I'm quite new to programming)
Jelte2357 wrote:
thank you logicaljoe, how would this work with powers and factorials? (sorry if I am asking easy/dumb questions I'm quite new to programming)


Decimal objects support all the usual arithmetic operations, provided that the arguments are integers or other Decimal objects so that precision isn't lost (i.e. no floats). Powers can thus be computed using the ** operator.

Factorials of integers can be calculated using the function in the math module; since the factorial of an integer is also an integer, you can perform operations on them and Decimals with no issue. Taking factorials of Decimals, though, is much harder, as you'd need to implement the Gamma function (the continuous extension of the factorial) with arbitrary precision (and, surprisingly, the decimal module doesn't do this for you).
kg583 wrote:
Decimal objects support all the usual arithmetic operations, provided that the arguments are integers or other Decimal objects so that precision isn't lost (i.e. no floats). Powers can thus be computed using the ** operator.


There is no decimal.pow or decimal.power or decimal.**, and even if i do Decimal(Decimal([pi with 100 digits]**2)).sqrt() the answer result will only ever have 15 correct decimal places. How do I fix this?
Jelte2357 wrote:
There is no decimal.pow or decimal.power or decimal.**, and even if i do Decimal(Decimal([pi with 100 digits]**2)).sqrt() the answer result will only ever have 15 correct decimal places. How do I fix this?


Decimal objects have their operators as bound methods, so if you wanted to use pow instead of **, it'd be [object].pow([power]) or decimal.Decimal.pow([object], [power]). The ** operator hooks into the pow implementation for Decimals, though, so it works just as well (and decimal.** isn't even valid as a method name).

The reason you are not getting the result you want is because you are squaring before the object is cast to a Decimal, so you're bound to lose precision. Also, all the operators return Decimal objects, so there's no need to cast more than once.
but decimal.Decimal doesn't have a pow attribute.
there is a Decimal.__pow__ that does work but it doesnt work how i want it to.


Code:
from decimal import *
from math import *
getcontext().prec = 50
a=Decimal(3.14159265358979323846264338327950288419716939937510)
x=Decimal.__pow__(a,2)
y=Decimal(x).sqrt()
print(y)

3.141592653589793X1159979634685441851615905761718750
3.14159265358979323846264338327950288419716939937510


the X is where the output goes wrong.

Now I dont have any idea what is wrong
You're causing approximation as a binary float when constructing a decimal value from a literal. Writing the literal as a string avoids that:

Code:
>>> import decimal
>>> from decimal import Decimal
>>> decimal.getcontext().prec = 50
>>> a = Decimal(3.14159265358979323846264338327950288419716939937510)
>>> a
Decimal('3.141592653589793115997963468544185161590576171875')
>>> a = Decimal('3.14159265358979323846264338327950288419716939937510')
>>> a # Note that this value is different from the above
Decimal('3.14159265358979323846264338327950288419716939937510')
>>> (a ** 2).sqrt()
Decimal('3.1415926535897932384626433832795028841971693993751')

(You'll also notice idiomatic use of __pow__ via the exponentiation operator in my example.)
Here’s a program I wrote to calculate pi. It displays 7 digits at a time. If only 6 show, then there should be a leading 0. On my iPad, this program (modified for the iPad) shows 200,000 digits in 204 seconds.

On my Ti 84+ CE, it takes 31 seconds to show 100 digits, 181 seconds for 250 digits.


ClrHome
Input "NBR DIGITS ",D
startTmr→Q
iPart(D/7)+1→S
10^7→T
For(Z,1,D
5*(Z-1)+3→L1(Z
End
For(M,1,S
0→C
For(Z,D,1,-1
L1(Z)*T+C→V
27*((Z-1)^2)+27*(Z-1)+6→B
V-iPart(V/B)*B→L1(Z
iPart(V/B)*(2*((Z-1)^2)-(Z-1))→C
End
V-iPart(V/T)*T→L1(1
Disp iPart(V/T
End
Disp "SECONDS "
checkTmr(Q)
Most likely one of my last questions about this topic,

why doesn't this program output more than 15 correct decimals?
for info, this is chykovsky's algorithm.


Code:
from math import*
from decimal import *
getcontext().prec = 500
R=0
a=0
b=0
while R!=500:
    b+=Decimal(((((-1)**a)*factorial(6*a)*((545140134*a)+13591409))/((factorial(3*a))*((factorial(a))**3)*((640320)**(3*a+(3/2))))))
    c=Decimal(12*b)
    d=Decimal(1/c)
    a+=1
    R+=1
    print(d)
You're doing a large computation in terms of types other than Decimal again, so once again you're limited to float precision.

Annotating the important types:

Code:
a: int = 0
b: int = 0

t0: int = -1 ** a
t1: int = factorial(6 * a)
t2: int = 545140134*a
t3: int = factorial(3 * a)
t4: int = factorial(a) ** 3
# 3/2 is a float, so t5 is also a float
t5: float = 3 * a + (3 / 2)

b += Decimal(
    (
        (t0*t1*(t2+13591409))
        /
        (t3*t4*(640320**t5))
    )
)

You should take care that all values used in your expressions are actually Decimals to avoid this sort of thing, though only the division is actually problematic here because every other value used is an integer.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement