Berechnung eines sinh abbrechen, wenn 16. Nachkommastelle sich nicht mehr ändert

babuschka

Top Contributor
Hallo Leute,

ich hoffe, ich bin hier richtig. Ich sitze seit Ewigkeiten am Ende einer Aufgabe. Mein Programm soll den Sinus Hyperbolicus vom jenen Zahlen berechnen, die aus der Main-Methode übergeben werden. Das soll es in der Methode sinh tun. Dazu brauche ich auch eine Methode, die mir die Fakultät berechnet (der Formel wegen). Das habe ich alles schon erledigt. Uns wurde ganz oben dieses EPSILON vordeklariert. Ich kann damit nur leider garnichts anfangen. Die Berechnung soll abbrechen, wenn die 16. Nachkommastelle des Ergebnisses sich nicht mehr ändert. Wie kann ich das jetzt anstellen??? Wahrscheinlich unter der Verwendung von EPSILON....

Achso....Bitte macht mich jetzt nicht darauf aufmerksam, dass es eine math.sinh Funktion gibt....das weiß ich...darf ich aber nicht benutzen^^ 🙁

Bitte helft mir!

Java:
public class Program {
	public final static double EPSILON = 1E-16;

	public static double sinh(final double x) {

		double erg;
                double lol =0;
		for (int i = 1; i < BED; i++) // BED: nach sechzehnter dezimalstelle
		{
			erg = (Math.pow(x, (2 * i - 1))) / fac(2 * i - 1);
			lol=erg;
			
		}

		return lol;

	}

	public static double fac(double fac) {
		int r = 1;
		for (int i = 1; i <= fac; i++)
			r *= i;
		return r;
	}

	public static void main(String[] args) {

		System.out.println("sinh(0)=" + sinh(0.0));
		System.out.println("sinh(1)=" + sinh(1.0));
		System.out.println("sinh(-1)=" + sinh(-1.0));
		System.out.println("sinh(1000)=" + sinh(1000.0));
		
	}

}
 
Du willst den sinh mittels Taylorreihe bestimmen?
Java:
for (int i = 1..
    erg = (Math.pow(x, (2 * i - 1))) / fac(2 * i - 1);
    lol=erg;
Da sind zunächst mal ein paar Fehler drin:
- i muss bei 0 beginnen
- ausserdem gilt
Code:
erg = (Math.pow(x, (2*i [B]+[/B] 1))/fac(2*i [B]+[/B] 1);
- es fehlt die Summierung
Code:
lol = lol + erg;
oder kurz
Code:
lol += erg;

Bzgl Abbruchbedingung:
- ich würde das statt mit einer for mit einer while-Schleife machen
- musst Du das vorherige Zwischenergebnis in einer weiteren Variablen speichern
- die Schleife muss dann abbrechen sobald der
Code:
Betrag von (neuesErgebnis - zwischenErgebnis) < EPSILON
 
Ok, habe das alles nochmal überarbeitet....Es funktioniert aber nur teilweise...
Für x=0 und x=1 stimmt der output. Für x=-1 und x=1000 ist es totaler blödsinn...
Kann mir jemand den letzten Denkanstoß geben? 🙂


Java:
public class Program {
	public final static double EPSILON = 1E-16;

	public static double sinh(final double x) {

		double n=1;
		double sum=0, sumtemp=0;


		do
		{
		sumtemp = sum; 
		sum += (Math.pow(x, (2 * n - 1))) / fac(2 * n - 1);
		n++;
		//System.out.println("Sum: "+sum); 
		}
		while ((sum-sumtemp)>EPSILON);


		return sum;

		}


	

	public static double fac(double fac) {
		int r = 1;
		for (int i = 1; i <= fac; i++)
			r *= i;
		return r;
	}

	public static void main(String[] args) {

		System.out.println("sinh(0)=" + sinh(0.0));
		System.out.println("sinh(1)=" + sinh(1.0));
		System.out.println("sinh(-1)=" + sinh(-1.0));
		System.out.println("sinh(1000)=" + sinh(1000.0));

	}

}
 
(Math.pow(x, (2*i + 1))/fac(2*i + 1);

eq.latex


- die Schleife muss dann abbrechen sobald der Betrag von (neuesErgebnis - zwischenErgebnis) < EPSILON

Wobei es vllt etwas verständlicher wäre mit
Java:
do {
  // ...
  double addend = //taylor
  sum += addend;
}while (Math.abs(addend) > EPSILON);
finde ich zumindest

Edit: Apropos verständlich, ich würde dir (carpenoctem) empfehlen den Code sinnvoll einzurücken...
 

Zurück
Oben