0

I get the error java.lang.StackOverflowError when I try to run my code:

public class calc {
    public static void main(String[] args){
double zahl = 847362;
System.out.println( wannawoerk(zahl) );

}


public static double wannawoerk(double zahl){
    if (zahl == 1)
        return 1;
    else
        return wannawoerk(zahl - 1) + zahl;
} }

Is there any workaround for this problem? I have to use a recursive function without for, while, etc.

Hans Müller
  • 33
  • 1
  • 7
  • 3
    Why `double`? The problem here is either A) The stack can't go 847,361 frames deep (think about it, that's a lot), or B) IEEE-754 double-precision binary floating point fun and games. I suspect (A), but... – T.J. Crowder Oct 17 '16 at 12:55
  • "Thrown when a stack overflow occurs because an application recurses too deeply." – eldo Oct 17 '16 at 13:00

4 Answers4

9

Repeated subtraction of 1 from zahl will eventually give you 1. (Floating point subtraction by an integer on integers in this range is exact: you'd only get oddities above the 53rd power of 2).

Your problem is that your JVM is probably not going to allow you that many recursive calls.

A stack depth approaching one million is really not going to end well!

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • For mentioning that integers up to 2^^54 are represented without error. +1 64-bit float has a 53-bit mantissa as the top bit is always 1 for normalised number only the bottom 52 bits need to be stored. 2^^54 is the last ok integer as it's a power of two but 2^^54+1 can't be represented. – Peter Lawrey Oct 17 '16 at 13:23
  • Hum. We'll meet in the middle. I think the first number that can't be represented is 2^^53 + 1 – Bathsheba Oct 17 '16 at 14:00
1

If you're required to use recursion, you could increase memory available for stack: java -Xss256m YourClass - sets stack to 256MB max.

In real world, you'd most probably use a while loop for this. Or, in this case, compute it right away (you don't need recursion for the thing you are computing), but I guess that's not the point.

Jiri Tousek
  • 12,211
  • 5
  • 29
  • 43
  • @Bathsheba You're right. I didn't bother to verify it as IMO it is secondary and not to the point of question. But I see having wrong formula in the answer is not a good idea and could mislead someone, so I removed it. – Jiri Tousek Oct 17 '16 at 13:54
  • Thanks for the answer, Jiri. – Hans Müller Oct 17 '16 at 18:32
1

The stack is not unlimited and Java doesn't have tail call optimisation. The simplest solution is to have the method

return zahl * (zahl + 1) / 2;

Ideally you wouldn't use double instead you would write

public static long sumUpTo(int n) {
    return n * (n + 1L) / 2;
}

To make any sane optimisation you need a more realistic method.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
0

This example of yours is very also illustrated in this comment! along with a few other very detailed explanations of this issue, why it happens and how to handle it.

Community
  • 1
  • 1
Simon Jensen
  • 488
  • 1
  • 3
  • 19
  • 1
    I did consider it, but since the general question and explanation was different and only one of the answers provided in the link was similar I wasn't too sure about it. So simply not to ruin anything, I would leave that decision to someone more competent in that matter than myself – Simon Jensen Oct 17 '16 at 13:39