Datentypen Warum so nur Fakultät nur bis 8?

iTutHD

Mitglied
Hallo,
Ich habe eine frage zum meinem folgenden Code.

Code:
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        long x = 0;
        if(args.length == 1){
            x = Long.parseLong(args[0]);
        }
        else{
            System.err.println("Fehler bei Kommandoübergabe!");
        }
        System.out.println(fact(x));
    }
   
    public static long add(long x, long y){
        return x + y;
    }
   
    public static long mult(long x, long y){
        if (y > 1){
            return (mult(x,y-1)+x);
        }
        else{
            return x;
        }
    }
   
    public static long fact(long x){
        if(x > 1){
            return (mult(x, fact(x - 1)));
        }
        return x;
    }

Ich habe die Übungsaufgabe bekommen, eine rekursive Implementation zu schreiben um nur mit hilfe von Addition zu multiplizieren. Dafür habe ich die Methode mult gemacht. Diese muss laut aufgabenstellung die Methode add zum addieren benutzen, welche nur die Übergabe von 2 zahlen unterstützt. Dannach sollte ich das gleiche für die berechenung von Fakultäten machen und dazu die Methode mult rekursiv aufrufen.
Meine Frage ist jetzt folgende. Warum kann mein Code nur bis Fakultät 8 rechnen? Ich benutze ja die ganze Zeit den Datentyp long welcher ja mit seinen 64-Bit die zur Verfügungstehen weiter als bis 40320 kommen können sollte.

Kann mir wer erkären, wie genau das zustande kommt? Es geht mir nicht darum, dass ich das Programm weiter rechnen lassen können muss, sondern nur um eine verständliche Erklärung warum dies so ist.

Danke und grüße!
 
Hast du etwas den Fehler "java.lang.StackOverflowError" bekommen ?
Bei rekursiven Methoden Programmieren muss man sich irgendwann mit der Stack-Größe beschäftigen. Bei dir ist es nun soweit.

Wenn ich den Stackspace beispielsweise auf 2 MByte vergrößere ( -Xss2m ), dann kann ich auch 9! berechnen.
 
Erstmal zwei allgemeine Sachen:
1. Du sagst selber du sollst bei der Multiplikation nur deine Add Methode benutzen, das tust du aber nicht
2. Deine Multiplikation funktioniert nur mit Zahlen größer gleich eins

Nun zum Problem, durch die ganzen rekursiven Aufrufe erhälst du eben eine StackOverflowException. Hauptproblem ist hier vor allem deine rekursive Multiplikationsmethode. Betrachte einfach mal das Beispiel 10*10, hier würde eine multiplikationsmethode sich selbst 9 weitere male aufrufen. Bei der Fakultät hast du aber weitaus größere Zahlen, sodass du unmengen an rekursiven Aufrufe hast.
 
Wenn du mehr ausrechnen möchtest, dann solltest du es nicht rekursiv implementieren:

Java:
    if ( n >= 0 )
    {
      while ( n > 1 )
      {
        fakultaet = fakultaet * n;
        n   = n - 1;
      }
      System.out.println( "Fakultaet ist " + fakultaet );
    }
 
Danke für die Antworten!
Die Antworten haben mir sehr geholfen!

@InfectedBytes
Zu 1.: Jop stimmt habe ich zur Fehlersuche geändert und vergessen wieder raus zu nehmen...
habe jetzt die zeile abgeändert 🙂
Zu 2.: Danke habe ich noch nicht so drüber nachgedacht... Bessere ich gleich aus.
Ich soll ja leider Rekursion benutzen. Soll das ganze denke ich nur nochmal als Übung verdeutlichen aber danke für deine itterative Lösung!

@Dompteur

Danke! Mit -Xss2m klappt es noch nicht aber mit 4 irgend wie schon

Sollte so alle Fehler behoben haben oder?
Code:
package rekursion;

public class fakultaet {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        long x = 0;
        if(args.length == 1){
            x = Long.parseLong(args[0]);
        }
        else{
            System.err.println("Fehler bei Kommandoübergabe!");
        }
        System.out.println(fact(x));
    }
   
    public static long add(long x, long y){
        return x + y;
    }
   
    public static long mult(long x, long y){
        if (y > 1){
            return (add(x,mult(x,y-1)));
        }
        else if(y < 1){
            return(add(y,mult(y, x-1)));
        }
        else{
            return x;
        }
    }
   
    public static long fact(long x){
        if(x > 1){
            return (mult(x, fact(x - 1)));
        }
        return x;
    }
}
 
Zuletzt bearbeitet:

Zurück
Oben