1

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
Mo Samani
  • 53
  • 1
  • 9
  • 1
    your `factorial` variable is probably just getting too big since factorials tend to do that, you look at [this link](http://stackoverflow.com/questions/16174399/overflowerror-long-int-too-large-to-convert-to-float-in-python) for ways to bypass that – R Nar Nov 09 '15 at 19:03
  • 1
    Your while loop looks like it is missing a negative sign. Why not just `abs(r) > 10**(-12)`? – John Coleman Nov 09 '15 at 19:11
  • What version of Python are you using? My 2.7.5 version handles this cleanly, spitting out a very nice approximation of root(2). – Prune Nov 09 '15 at 19:16
  • Also, I strongly recommend that you make your loop limits easier to read, and perhaps interdependent. 1.0E-18 is much easier to comprehend ... and to error-check. – Prune Nov 09 '15 at 19:17

3 Answers3

3

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.

John Coleman
  • 51,337
  • 7
  • 54
  • 119
  • can you please tell me how can i get two numbers as one input? so that my function can get (n,k) – Mo Samani Nov 09 '15 at 19:28
  • @MohammadHoseinKhalili I assume you mean with `input` (or `raw_input` in Python 2). Maybe something like `nums = input("Enter n, k, separated by a space")` followed by `nums = nums.split()` followed by `n = int(nums[0])` followed by `k = int(nums[1])` – John Coleman Nov 09 '15 at 19:32
  • thanks it worked...can you please show me a way to limit digits after the dot ? i want to limit numbers to the k...for example sum is 0.70123 and by k=2 i want the sum to be 0.70 , i appreciate it... – Mo Samani Nov 09 '15 at 19:42
  • @MohammadHoseinKhalili Use `round` to round the number itself -- or Google "Python string formatting" to find out how to control how the data is printed. – John Coleman Nov 09 '15 at 19:46
1

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))
Prune
  • 76,765
  • 14
  • 60
  • 81
0

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.

0x539
  • 1,489
  • 1
  • 13
  • 30