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



## babuschka (5. Nov 2010)

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!


```
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));
		
	}

}
```


----------



## madboy (5. Nov 2010)

Breche das 
	
	
	
	





```
for
```
 ab wenn | vorheriges Ergebnis - aktuelles Ergebnis | < EPSILON


----------



## babuschka (6. Nov 2010)

Vielen Dank schonmal für die Antwort...

...aber wie deklariere ich meine Ergebnisse? Was sind meine Ergebnisse?


----------



## Michael... (6. Nov 2010)

Du willst den sinh mittels Taylorreihe bestimmen?

```
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 
	
	
	
	





```
erg = (Math.pow(x, (2*i [B]+[/B] 1))/fac(2*i [B]+[/B] 1);
```
- es fehlt die Summierung 
	
	
	
	





```
lol = lol + erg;
```
 oder kurz 
	
	
	
	





```
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 
	
	
	
	





```
Betrag von (neuesErgebnis - zwischenErgebnis) < EPSILON
```


----------



## babuschka (6. Nov 2010)

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? 



```
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));

	}

}
```


----------



## Michael... (6. Nov 2010)

siehe:


Michael... hat gesagt.:


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





Michael... hat gesagt.:


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


----------



## babuschka (7. Nov 2010)

2*n-1 ist schon "richtig", zumindest steht es auf dem Übungsblatt in der Forumel so.


----------



## Illuvatar (7. Nov 2010)

Michael... hat gesagt.:


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











Michael... hat gesagt.:


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



Wobei es vllt etwas verständlicher wäre mit

```
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...


----------

