0

I have to write simple code to calculate cos(x) value with McLaurin series approximation. I have to do it recursively. Problem is that with too big angle (param in radians) or too high precision (loop has to stop while last term is smaller or equal than given ε) I get StackOverFlowError. At first I did it non-recursively and it worked perfectly, but it's not fully correct according to assignment. I tried to decrease number of calls for term, but I couldn't fix this. Is there any way to improve this code?

    public int factorial(int n) {
       int result = 1;
       for (int i = 1; i <= n; i++) {
           result = result * i;
       }
       return result;
   }

    public double term(double x, int n) {
        return Math.pow(-1, n) * (Math.pow(x, 2*n) / factorial(2*n));
    }

    public double laurin(String param, String epsilon) {
        double x, eps;
        double result = 1;
        int n = 0;

        x = Double.parseDouble(param);
        eps = Double.parseDouble(epsilon);

        while(Math.abs(term(x, n)) > eps) {
            result += term(x, n) * (term(x, n+1) / term(x, n));
            n++;
        }

        return result;
    } 

Changing factorial(int n) to non-recursive hasn't changed much, I still get an error real quick.

JayL
  • 101
  • 1
  • 2
  • 13
  • Your `factorial` method is pretty horrible. Use a loop; and use memoization. – Boris the Spider Dec 21 '15 at 00:54
  • Another solution is to run it with a bigger stack, like [here](http://stackoverflow.com/questions/2127217/java-stack-overflow-error-how-to-increase-the-stack-size-in-eclipse) – Joseph Young Dec 21 '15 at 00:57
  • @JosephYoung with a recursive factorial algorithm, you will always run into SO with big enough calculations - increasing stack size is a temporary solution at best. – Boris the Spider Dec 21 '15 at 01:00
  • The above comments by @BoristheSpider are entirely correct, but probably beyond the scope of your assignment, if you modify your `term` function to take the factorial value, you won't need to recalculate it each time within the body of `term`. Hint, calculating the factorial of n+1 is trivial when you have the the factorial of n. – jonsca Dec 21 '15 at 01:01
  • @BoristheSpider Why is it horrible? It's the most basic recursive algorithm that I know, I was taught to do it that way. By memoization you mean storing value of factorial in variable, mayby in an array? – JayL Dec 21 '15 at 11:33
  • @jonsca So again, saving value of factorial in an array would be a proper solution? – JayL Dec 21 '15 at 11:33
  • Bubble sort is the most basic sorting algorithm - this does mean that it ever should be used. Java has no tailrec optimisation in the compiler, so you need to be very wary of stack size. You don't need to store values in an array, you don't even need to calculate the factorial! You are operating in a loop - simply remember the previous value and multiply. – Boris the Spider Dec 21 '15 at 14:45
  • 1
    If you are still getting errors, then this smells of overflow - using an `int` for factorials is usually a bad call - an `int` can hold up to `2^32 -1` as a maximum value - this is somewhat less than [`13!`](http://www.forums.hscripts.com/viewtopic.php?f=13&t=2212). Even `long` can only go up to `20!`... – Boris the Spider Dec 21 '15 at 14:47
  • @BoristheSpider Well, changing type to `double` in `factorial` actually helped, I never would have thought about it. Thank you very much. – JayL Dec 21 '15 at 16:33
  • The largest integral value of a `double`, such that all smaller integral values can be represented is [`2^53`](http://stackoverflow.com/a/1848762/2071828) - this is actually less than a `long`. For approximation, `double` may be okay as the loss of precision is probably swallowed by approximation error - but it may prevent your series from converging for certain values. You should really be using a `BigInteger`. – Boris the Spider Dec 22 '15 at 09:31
  • Well, I have already sent this code to my teacher, so I just hope it'll be enough. But thanks for advice, I'll keep that in mind. I wasn't using big values for so long that I forgot about that, shame on me. – JayL Dec 25 '15 at 18:40

0 Answers0