Reputation: 53
my homework is to write a code which contains a function that calculates the sinx taylor series and gives the amount back. the function must get (n,k) which n is the requested number for sine,and k is the digits that function must calculate after the dot. first i neglected k since its easy to limit the numbers after the dot,and wrote a function that just calculates sinx taylor,so i gave it a specific range for r(r is every sentence of the taylor series):
def taylor(n,k):
s= ((math.pi)/180)*n
ex = s
sign = 1
factorial = 1
sum=0
i=1
r=1
while r>0.00000000000000000001 or r<0.0000000000000000000001 :
r= ex*sign/factorial
ex = ex*s*s
sign = sign*(-1)
factorial=factorial*(i+1)*(i+2)
i= i+2
sum = sum + r
return sum
import math
print(taylor(45,1))
i just don't know why if i set amount of r larger than this (i.e 0.1) i get this error:
Traceback (most recent call last):
File "/Users/modern/Desktop/taylor.py", line 22, in <module>
print(taylor(45))
File "/Users/modern/Desktop/taylor.py", line 12, in taylor
r= ex*sign/factorial
OverflowError: int too large to convert to float
Upvotes: 1
Views: 280
Reputation: 1496
I'm not sure what you mean with
if i set amount of r larger than this (i.e 0.1)
and the condition of your while loop looks strange, but as R Nar pointed out, the error is caused by your value of factorial
is getting too large. I would not recommend using decimal
however since it is really slow. Rather take a look at gmpy which is built in order to get (really) fast arbitrary precision math.
Alternatively you could use Strinling's Approximation for calculating the large factorials.
Upvotes: 0
Reputation: 77910
You can handle your input with a leading question and a split, as @John Coleman suggested, although I'd do the assignment as a pair:
nums = input("Enter n, k, separated by a space")
n, k = nums.split()
Here is the cleaned-up program: the factor updates -- especially the factorial -- are reduced to changes from the previous term. I also canonized your loop limits to be more readable.
def taylor(n,k):
s = (math.pi/180)*n
s2 = s*s
sum = s
i = 1
r = s
converge = 1.0E-20
while r > converge or r < converge / 100 :
r *= -s2/((i+1)*(i+2))
sum += r
i = i+2
return sum
import math
print(taylor(45,1))
Upvotes: 1
Reputation: 52008
I'm surprised that this is an issue since I would think that r
gets below the error tolerance before it is a problem.
Note that what you really need is the reciprocal of the factorial. Instead of having a factorial variable that you divide by, you could have a variable, say, fact_recip
which is initialized as
fact_recip = 1.0
used like r= ex*sign*fact_recp
And updated via
fact_recip /= ((i+1)*(i+2))
this will handle the error that you are seeing, but I'm not sure if the round-off error would be an issue.
Upvotes: 3