Sin(x) rekursiv lösen

kilopack15

Aktives Mitglied
Hallo Leute!
Ich habe ein Problem und zwar soll ich ein Programm schreiben, dass den Sinus(x) im Bogenmaß ausrechnet. Gegeben ist diese Formel zur Errechnung:
mathformel.png
Ganz wichtig: Das ganze soll über Rekursion gelöst werden und abgebrochen wird die Methode, falls der Summand in der Klammer zwischen −1 ∗ 10^(−7) und 1 ∗ 10^(−7) liegt.

Meine (noch) falsche Lösung:
Java:
public class MathFormel {
    public static int i=0;
    public static double ergebnis = 0.0;
    //Fakultät
    public static double factorial(int fact){
        if(fact == 1){
            return 1.0;
        }
        else{
            return fact * (factorial(fact-1));
        }
    }
  
    //Term (-1)^i
    public static int termloeser1(int i){
        if((i % 2)==0){
            return 1;
        }else{
            return -1;
        }
    }
  
    //Term x^(2i+1)
    public static double termloeser2(double x, int i){
        double hilfe1 = x;
        for(int counter1 = 1; counter1 < ((2*i)+1); counter1++){
            x*=hilfe1;
        }
        return x;
    }
  
    public static boolean abbruchchecker(double x, int i){
        double abbruchraum = 0.0000001;
        double checkzahl = termloeser1(i) * ((termloeser2(x,i))/(factorial((2*i)+1)));
        if(checkzahl < abbruchraum && ((checkzahl * (-1)) > abbruchraum)){
            return false;
        }else{
            return true;
        }
    }
  
  
    public static double loeseRekursiv ( double x ) {
        ergebnis = termloeser1(i) * ((termloeser2(x,i))/(factorial((2*i)+1)));
        if(abbruchchecker(x,i)==false){
            return ergebnis;
        }else{
            i++;
            return ergebnis + loeseRekursiv(x);
        }
    }
Viel Code um nichts! Die ersten drei Methoden sind ganz einfach Termlöser und die 4. Methode ist für das Abbruchkriterium zuständig.
Das Problem: die methode loeseRekursiv(x) bricht nach dem zweiten Durchlauf ab und returned das Ergebnis, obwohl das Abbruchkriterium gar nicht erfüllt ist. Ich kann ums Verrecken den Fehler nicht finden. Findet ihr den Fehler und könnt mir helfen? :)
Vielen Dank im Voraus!
 
N

neoexpert

Gast
Java:
import java.util.*;

public class Main
{
    public static void main(String[] args)
    {
        System.out.println(sincos(Math.PI,1));
       
    }
    static double sincos(double x, int n){
        if(n>20)
            return 0.0;
       
        return sincos(x,n+2)+(Math.pow(-1,n/2)*Math.pow(x,n)/ fak(n));
    }
   
    static long fak(long n){
        if(n==1||n==0) return 1;
        return n*fak(n-1);
    }
}
 
N

neoexpert

Gast
Verbessert:
Java:
public class Main
{
    public static void main(String[] args)
    {
        System.out.println(sincos(Math.PI/2.0,1));
       
    }
    static double sincos(double x, int n){
        double term=Math.pow(-1,n/2)*Math.pow(x,n)/ fak(n);
        if(Math.abs(term)<Math.pow(10.0,-7))return 0.0;
        return sincos(x,n+2)+term;
    }
   
    static long fak(long n){
        if(n==1||n==0) return 1;
        return n*fak(n-1);
    }
}
 
Zuletzt bearbeitet von einem Moderator:
N

neoexpert

Gast
Mehr von solchen Aufgaben bitte.
Übrigens: schreibt man in den zweiten Parameter eine 0, erhält man Cosinus
 

InfectedBytes

Top Contributor
@neoexpert Dem TE bringt es nicht viel wenn du nen Code reinstellst, der nichts mehr mit seinem eigenen zu tun hat. Stattdessen wäre es hilfreicher wenn du auf seine Frage eingehen würdest etc.
Ansonsten solltest du nicht jedes mal Math.pow(10.0,-7) rechnen, sondern dass nur einmal machen.

@kilopack15 Wenn du schon mehrere Methoden nutzt, solltest du denen auch erstmal ordentliche Namen geben. Ansonsten wäre es gut wenn du deinen Code mal etwas aufräumst^^
Weiterhin solltest du keine statischen Variablen benutzen.
Ansonsten solltest du auch nicht immer alles doppelt berechnen. z.b. berechnest du den Summanden in der Klammer zweimal: einmal in löseRekursiv und einmal in abbruchchecker. Letzteress macht natürlich überhaupt keinen Sinn, dort solltest du nur prüfen ob der parameter (=der Summand) im entsprechenden Bereich liegt.
 

kilopack15

Aktives Mitglied
Danke für eure Hilfe! Ich habe vergessen zu sagen, dass ich die Math. Biblio von java nicht verwenden darf. Deshalb halt zwei Methoden mehr ;) Statische Variablen sind nur vorübergehend zum Testen in der main da. Danke für die weiteren hilfreichen Tipps. Morgen habe ich sicher eine neue Sicht auf die Aufgabe. Mir fällt auch gerade auf, dass ich mir da einiges sparen könnte, aber so ist das nunmal am Anfang :)
Morgen werde ich nochmal meine verbesserte Lösung hereinstellen und ggf. Fragen stellen!
 

kilopack15

Aktives Mitglied
Java:
    public int i=0;
    public double ergebnis;
    public double abbruchraum = 0.0000001;
   
    //Fakultät
    public double factorial(int fact){
        if(fact == 1){
            return 1.0;
        }
        else{
            return fact * (factorial(fact-1));
        }
    }
   
    public double potenz(double basis, int exp){
        double h = basis;
        if(exp == 0){
            return 1;
        }
        for(int counter1 = 1; counter1 < exp;counter1++){
            h*=basis;
        }
        return h;
    }

    public double loeseRekursiv ( double x ) {
        ergebnis = potenz(-1.0,i) * potenz(x,(2*i+1))/factorial(2*i+1);
        if((ergebnis < 0.0000001) && (-0.0000001 < ergebnis)){
            return ergebnis;
        }else{
            i++;
            return ergebnis + loeseRekursiv(x);
        }
    }
Überarbeitet und Tests zufolge richtig! Gibts was zu korrigieren?
 

InfectedBytes

Top Contributor
du definierst zwar abbruchraum, benutzt die variable aber nie.
Weder i, noch ergebnis sollten membervariablen sein. Das Ergebnis gibst du durch die Methode zurück, daher brauchst du es dir nicht separat merken. Die Laufvariable i solltest du einfach als extra parameter mitgeben und eben nicht als Objektvariable speichern.
 

kilopack15

Aktives Mitglied
Okay. Danke habs soweit verbessert. Das Ding heißt loeseRekursiv, weil ich es noch auf einen anderen Weg lösen soll und zwar mit Schleifen und ohne Methodenaufrufe. Die entsprechende Methode loeseSchleife sieht bei mir bis jetzt so aus
Java:
int i=0;
double ergebnis=0.0;
public double loeseSchleife ( double x ) {
        int term1;
        double term2=1.0;
        double term3=1.0;
      
        do{
         //Potenz (-1)^i 
        if((i%2)==0){
            term1 = 1;
        }else{
            term1 = -1;
        }
      //Potenz Zähler
        for(int counter2=1;counter2<=(2*i+1);counter2++){
            term2*=x;
        }
      //Fakultät
        for(int h1 =(2*i+1);h1>1;h1--){
            term3*=h1;
        }

        ergebnis=ergebnis + term1*(term2/term3);
        i++;
        }while((ergebnis < 0.0000001) && (-0.0000001 < ergebnis));
        return ergebnis;
    }
Sie bricht aber nach dem ersten Durchlauf ab und ich erkenne den fehler nicht. Weiß jemand von euch, was ich falsch gemacht habe?
 

InfectedBytes

Top Contributor
weil deine Bedingung nicht stimmt: ((ergebnis < 0.0000001) && (-0.0000001 < ergebnis));
Du lässt die Schleife momentan solange laufen wie ergebnis im Abbruchraum liegt.

Und auch hier hast du schon wieder Variablen unnötigerweise als Objektvariablen deklariert. Es macht überhaupt keinen Sinn das du i und ergebnis als Objektvariable speicherst!
 

kilopack15

Aktives Mitglied
Okay also einfach diese while-Bedingung negieren und die beiden Variablen in die Methode reinholen. Sieht dann bei mir folgendermaßen aus und liefert NaN beim Testen. Das verstehe ich nicht
Java:
    public double loeseSchleife ( double x ) {
        int term1;
        double term2=1.0;
        double term3=1.0;
        int i=0;
        double ergebnis=0.0;
      
        do{
          
        if((i%2)==0){
            term1 = 1;
        }else{
            term1 = -1;
        }
      
        for(int counter2=1;counter2<=(2*i+1);counter2++){
            term2*=x;
        }
      
        for(int h1 =(2*i+1);h1>1;h1--){
            term3*=h1;
        }

        ergebnis=ergebnis + term1*(term2/term3);
        i++;
        }while((ergebnis > 0.0000001) | (-0.0000001 > ergebnis));
        return ergebnis;
    }
Es dürfen übrigens keine weiteren Parameter zu der Methode mitgegeben werden.
 

Flown

Administrator
Mitarbeiter
Du kannst die Fakultät und die Potenz iterativ berechnen und musst dadurch diese nicht immer neu berechnen - gilt auch für deine rekursive Methode.

Tipp: Deine Abbruchbedingung kann man auch so schreiben:
Java:
do {
//...
} while(!(-1e-7 < step && step < 1e-7));
1e-7 == 1 * 10^-7 == 0.0000001
 
Zuletzt bearbeitet:

Flown

Administrator
Mitarbeiter
Also warum deine iterative Methode nicht funktioniert:
- Die Abbruchbedingung ist falsch (der aktuell Summand muss sich innerhalb von -1*10^-7 < summand < 1*10^-7 befinden, nicht die Summe)
- term2 & term3 werden außerhalb der Schleife deklariert, darum haben sie falsche Werte innerhalb der Schleife (also bitte die beiden Variablen in die Schleife ziehen)
 

Flown

Administrator
Mitarbeiter
Funktionierts jetzt auch? Am besten du postest hier deine Lösung, damit andere auch noch Hilfe erwarten können.
 

kilopack15

Aktives Mitglied
Leider funktioniert es noch nicht. So sieht es bis jetzt aus
Java:
public static double loeseSchleife ( double x ) {
        double ergebnis= 0.0;
        double term3= 1.0;
        int term1;
        double term2 = 1.0;
        double abbruchzahl =5;
        for(int i=0;(!(-1e-7 < abbruchzahl && abbruchzahl < 1e-7));i++){
           
           
        if((i%2)==0){
            term1 = 1;
           
        }else{
            term1 = -1;
        }
       
       
   
        if(i == 0){
            term2=1;
        }
        for(int counter2=1;counter2 <= (2*i+1);counter2++){
            term2 = term2 *x;
           
        }
       
       
        for(int h1 =(2*i+1);h1>1;h1--){
           
            term3*= h1;
        }

        ergebnis+= term1*(term2/term3);
        abbruchzahl  = ergebnis;
       
        }
        return ergebnis;
       
    }
Beim Testen läuft es aber schon und gibt nicht wie vorher 0.0 aus. Allerdings läuft es minutenlang ohne Ergebnis. Was ist da los? Was kann ich korrgieren?
 

Flown

Administrator
Mitarbeiter
Schau her:
- Die Abbruchzahl ist ein Schritt und nicht das gesamte Ergebnis.
- Die Abbruchzahl sollte auch sinnvoll initialisiert werden (Tipp: x).
- Das Ergebnis sollte auch sinnvoll initialisiert werden (Tipp: .... rate mal?).
- Die Variablen - wie letztes mal auch schon - term1/2/3 sollen in die Schleife!
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
R Hanoi rekursiv lösen Problem Java Basics - Anfänger-Themen 1
M Sudoku Rekursiv lösen Java Basics - Anfänger-Themen 9
G Sudoku rekursiv lösen Java Basics - Anfänger-Themen 10
H Passwort Brute Force rekursiv Java Basics - Anfänger-Themen 7
1 Array rekursiv durchlaufen Java Basics - Anfänger-Themen 8
E Rekursiv Objekte erzeugen - geht das? Java Basics - Anfänger-Themen 2
Cassy3 Binäre Bäume Rekursiv durchlaufen und bestimmte Elemente Zählen Java Basics - Anfänger-Themen 6
R0m1lly Kombinationen aus int array rekursiv Java Basics - Anfänger-Themen 2
L Rekursiv gegebenes Passwort herausfinden. Java Basics - Anfänger-Themen 2
P9cman Char Index rekursiv finden Java Basics - Anfänger-Themen 4
B Methoden Rekursiv festellen, ob eine Zahl gerade-oft vorkommt oder nicht Java Basics - Anfänger-Themen 4
S Methoden Methodenaufruf rekursiv zählen Java Basics - Anfänger-Themen 4
B Array nach Wert prüfen rekursiv Java Basics - Anfänger-Themen 5
sashady Zahlen rekursiv zerlegen und Ziffern addieren Java Basics - Anfänger-Themen 38
jhCDtGVjcZGcfzug Fibonacci Zahlen rekursiv und iterativ Java Basics - Anfänger-Themen 21
H Binominalkoeffizient tail-rekursiv in java darstellen Java Basics - Anfänger-Themen 0
GAZ Tribonacci Folge Rekursiv Java Basics - Anfänger-Themen 11
G Primzahlen von Rekursiv nach Iterativ Java Basics - Anfänger-Themen 6
A Ackermmanfunktion rekursiv Java Basics - Anfänger-Themen 4
A Binärbaum rekursiv durchsuchen und Referenz zurückgeben Java Basics - Anfänger-Themen 4
H Rekursiv Methode ausführen bei Kindern Java Basics - Anfänger-Themen 12
G Methode Rekursiv umschreiben Java Basics - Anfänger-Themen 8
L Jede zweite Ziffer entfernen (rekursiv) Java Basics - Anfänger-Themen 6
J Dateien in Verzeichnissen rekursiv auflisten wirft Exception Java Basics - Anfänger-Themen 4
D Pentagonale Nummern in Rekursiv Java Basics - Anfänger-Themen 14
O Enum Array Rekursiv abarbeiten Java Basics - Anfänger-Themen 44
E Weg-Suche-Problem rekursiv Java Basics - Anfänger-Themen 12
O Primzahl rekursiv mit einem Wert ohne i, wie? Java Basics - Anfänger-Themen 6
E Erste Schritte Potenz Negativ (rekursiv) Java Basics - Anfänger-Themen 2
O Rekursiv aufrufen Java Basics - Anfänger-Themen 2
F In List Rekursiv suchen Java Basics - Anfänger-Themen 12
F Iterativ in Rekursiv Java Basics - Anfänger-Themen 2
S Fibonacci Zahlen rekursiv Java Basics - Anfänger-Themen 1
L Rekursiv zwei Strings vergleichen Java Basics - Anfänger-Themen 3
B Fakultätsfunktion Rekursiv Berechnen aber mit Array Java Basics - Anfänger-Themen 10
J Fibonacci -Folge rekursiv berechnen Java Basics - Anfänger-Themen 18
B Wie kann ich Linien rekursiv zeichnen? Java Basics - Anfänger-Themen 4
T Rekursiv Tiefe eines binären Suchbaums ermitteln Java Basics - Anfänger-Themen 22
P Methoden Arrays.AsList kleinste Zahl ausgeben Rekursiv Java Basics - Anfänger-Themen 9
W A hoch N Rekursiv Java Basics - Anfänger-Themen 3
K Rechtecke rekursiv zeichnen Java Basics - Anfänger-Themen 20
V Quadrate rekursiv zeichnen Java Basics - Anfänger-Themen 7
M Fibonacci rekursiv mittels Cache Java Basics - Anfänger-Themen 17
E Binärbaum - von rekursiv zu iterativ Java Basics - Anfänger-Themen 10
Y Rekursiv Palindrom herausfinden Java Basics - Anfänger-Themen 5
B Fibonacci Zahlen rekursiv Array Java Basics - Anfänger-Themen 12
M String rekursiv Spiegeln mit Originalwort davor Java Basics - Anfänger-Themen 3
K Türme von Hanoi - Rekursiv. Java Basics - Anfänger-Themen 1
T MergeSort rekursiv programmieren Java Basics - Anfänger-Themen 8
M Zahlenpyramide rekursiv programmieren Java Basics - Anfänger-Themen 7
hello_autumn Potenz selber berechnen, Rekursiv. Java Basics - Anfänger-Themen 6
V Text wüerfeln-Rekursiv Java Basics - Anfänger-Themen 4
J Baum rekursiv durchlaufen Java Basics - Anfänger-Themen 2
D Münzverteilung Möglichkeiten | Rekursiv Java Basics - Anfänger-Themen 3
D Rekursiv Kombinationen ausgeben klappt nur bei einer Wiederholung Java Basics - Anfänger-Themen 4
shiroX OOP String rekursiv zurückgeben Java Basics - Anfänger-Themen 6
Z Fibonacci rekursiv meine Erklärung stimmt so? Java Basics - Anfänger-Themen 2
S java rekursiv iterativ hilfee :s Java Basics - Anfänger-Themen 5
E Erste Schritte Pi, rekursiv Java Basics - Anfänger-Themen 6
A Frage Methode ggt Rekursiv Java Basics - Anfänger-Themen 5
E Hanoi-Varianten rekursiv Java Basics - Anfänger-Themen 2
P Hanoi rekursiv zu iterativ umbauen Java Basics - Anfänger-Themen 20
P Mittelwert rekursiv Java Basics - Anfänger-Themen 13
E Integral Rekursiv Java Basics - Anfänger-Themen 15
M MergeSort rekursiv Java Basics - Anfänger-Themen 2
D Ziffer in Zahl Rekursiv Java Basics - Anfänger-Themen 4
B Array rekursiv untersuchen Java Basics - Anfänger-Themen 21
I Rekursiv Java Basics - Anfänger-Themen 13
C Rekursiv Zahlenfolgen berechnen mit zwei Variablen Java Basics - Anfänger-Themen 5
K Rekursiv zu Literal Java Basics - Anfänger-Themen 12
R Verzeichnisse rekursiv nach Dateiduplikaten durchsuchen Java Basics - Anfänger-Themen 5
L File Tree rekursiv Java Basics - Anfänger-Themen 10
W Binomialkoeffizient iterativ/rekursiv Java Basics - Anfänger-Themen 2
X Addition rekursiv ohne Schleife Java Basics - Anfänger-Themen 10
E Datentypen ein java problem rekursiv loesen Java Basics - Anfänger-Themen 2
K indexOf selbst rekursiv definieren Java Basics - Anfänger-Themen 4
M Fibonacci-Linear und Rekursiv Java Basics - Anfänger-Themen 14
J Java Rekursiv vs(zu) Iterativ Hilfe Java Basics - Anfänger-Themen 3
D preOrder, inOrder, postOrder rekursiv zusammensetzen aus String Java Basics - Anfänger-Themen 1
K Binomialkoeffizient rekursiv berechnen Java Basics - Anfänger-Themen 8
J eulersche rekursiv berechnen Java Basics - Anfänger-Themen 6
J Suchbaumeigenschaft rekursiv programmieren Java Basics - Anfänger-Themen 3
T Rekursiv Vokale zählen Java Basics - Anfänger-Themen 19
G Bestimmte Ebene eines Baumes rekursiv ausgeben Java Basics - Anfänger-Themen 49
F Sortieralgorithmus von rekursiv auf iterativ? Java Basics - Anfänger-Themen 21
S Stringlänge Rekursiv ermitteln Java Basics - Anfänger-Themen 2
dognose Verzeichnis rekursiv auslesen / beschränkte Apis. Java Basics - Anfänger-Themen 6
0 a hoch b rekursiv - wie stoppen? Java Basics - Anfänger-Themen 3
T Ordnerstrucktur rekursiv auslesen Java Basics - Anfänger-Themen 9
G Rekursiv die größte Zahl eines Arrays Java Basics - Anfänger-Themen 6
G Rekursiv Array Elemente quadrieren Java Basics - Anfänger-Themen 2
N Fibo Zahlen:iterativ,rekursiv Anzahl der Additionen zählen Java Basics - Anfänger-Themen 2
P Permutationen einer Tour rekursiv Java Basics - Anfänger-Themen 4
G Baumstruktur rekursiv durchlaufen Java Basics - Anfänger-Themen 2
B Kürzesten Weg zwischen mehreren Punkten finden (rekursiv) Java Basics - Anfänger-Themen 5
L Kombinationen einer Menge rekursiv berechnen Java Basics - Anfänger-Themen 11
J BinBaum rekursiv ausgeben Java Basics - Anfänger-Themen 9
W Rekursiv Zeichen einfügen Java Basics - Anfänger-Themen 6
M Verzeichnisse rekursiv durchlaufen und dann RegEx Java Basics - Anfänger-Themen 6
G Array rekursiv teilen und aufsummieren Java Basics - Anfänger-Themen 9

Ähnliche Java Themen

Neue Themen


Oben