# Sinus Methode selbst entwickeln ohne Math.Bibliothek



## DerPeter (8. Dez 2009)

Hallo,
...diverse sachen gelöscht zwecks google...

Nachfolgend habe ich mal den Hunz von mir eingefügt an dem ich seit gestern Abend sitze.

Es funktioniert vorne und hintenrum nichts richtig. Ich dachte mir einfach ich mach 2 Schleifen für den Nenner und den Zähler, dividiere alles schön mit dem jeweiligen Vorzeichen und ziehe das Ergebnis meiner temporären Variable ab. Anschließend kopiere ich die Variable in eine andere Variable. Und im nächsten Durchlauf subtrahiere ich das neue durch das alte Ergebnis um zu schauen ob die Differenz kleiner dem "EPS" ist. Wenn JA, dann Abbruchkriterium. Irgendwie hab ich einen großen Denkfehler :-/

Hoffentlich kann mir einer helfen 


```
public class Sinus {

		public static void main(String[] args) {
			
			System.out.println(getSin(3.14159265,1E-10));

	}
		
		public static double getSin(double x, double eps){
			// Variablen instanziieren
			double result;
			double vorzeichen = -1;
			double tempEps = 0.0;
			
			double temp1 = 0.0;
			double temp2 = 0.0;			
						
			double num = x;
			double denum = 1.0;	
			
			int i = 1;
			int n = 1;
			
			int faki = 1;
			int fakn = 2;
						
			while (tempEps <= eps) {
				
				vorzeichen *= -1;
								
				// Nenner erhöhen : Mit sich selbst multiplizieren!
				while (i<n){
					num *= num;
					i++;
					System.out.print(num);
				}
				// Zähler erhöhen
				while (faki<fakn){
					denum *= faki;
					faki++;
					System.out.print("/"+denum+"\n");
				}
				
				temp1 += vorzeichen*(num/denum);
				
				tempEps = temp2-temp1;
				System.out.println(tempEps);
				
				temp2 = temp1;
				
				n += 2; // Schleife immer um +2 erhöhen.
				i=0;
				fakn += 2;
				faki=0;
								
			}
			
			
			return tempEps;
		}

}
```


----------



## SlaterB (8. Dez 2009)

irgendwo steht faki=0;
welches in denum dann eingerechnet ist, -> denum ist immer 0,

bei num rechnest du num *= num;
aus x wird so x^2, x^4, x^8, x^16 usw.,

einfachste Rechenschritte, die man auch leicht mit System.out.println nachprüfen könnte..


----------



## DerPeter (8. Dez 2009)

Hallo,
ja die Kleinigkeiten hab ich ja schon gelöst. Der neue Code sieht so aus : 

Jedoch bekomme ich nur die ersten 2 Schritte richtig hin


```
3.14159265/1.0
31.00627657401031/6.0
```

Die Werte sind richtig, laut Taschenrechner. 
Aber in der nächsten Zeile spuckt er mir dann folgendes aus :


```
29809.099026889457/120.0
```

Das ist bissel argh daneben. Aber warum? FAK berechnet er jetzt anscheinend richtig (1,6,120,5040...) nur X berechnet er falsch :-/


```
public class Sinus {

		public static void main(String[] args) {
			
			System.out.println(getSin(3.14159265,1E-10));

	}
		
		public static double getSin(double x, double eps){
			// Variablen instanziieren
			double result;
			double vorzeichen = -1;
			double tempEps = 0.0;
			
			double temp1 = 0.0;
			double temp2 = 0.0;			
						
			double num = x;
			double denum = 1.0;	
			
			int i = 1;
			int n = 1;
			
			int faki = 1;
			int fakn = 1;
						
			while (tempEps <= eps) {
				
				vorzeichen *= -1;
								
				System.out.print(num);
	

				while (faki<=fakn){
					denum *= faki;
					faki++;
				}
				
				System.out.print("/"+denum+"\n");
				
				temp1 += vorzeichen*(num/denum);
				//System.out.println("Temp1: "+temp1);
				
				tempEps -= vorzeichen*temp1;
				System.out.println("TempEps: "+tempEps);
				
				temp2 = temp1;
				//System.out.println("Temp2: "+temp2);
				num = (num*num*num);

				fakn += 2;
				faki = 1;
				denum = 1.0;
								
			}
			
			
			return temp1;
		}

}
```


----------



## SlaterB (8. Dez 2009)

> num = (num*num*num);
hat offensichtlich immer noch wenig mit der Formel zu tun

der Wert 29809 ist aber verständlich, 31 * 31 * 31


----------



## DerPeter (8. Dez 2009)

Hallo,
ja das war ehrlich gesagt peinlich von mir :autsch:

Hab es natürlich abgeändert in


```
num *= (x*x)
```

Werte passen auch gut ^^


```
3.14159265/1.0
31.00627657401031/6.0
306.0196830368891/120.0
3020.2932036184748/5040.0
29809.099026889453/362880.0
```

Nun kommen wir zum eigentlichen Problem. Das Ergebnis von Sinus(Pi) soll ja wohl etwas mit 0.05480 ergeben.

Meine TEMP1-Ausgabe nähert sich aber leider keineswegs der Zahl.


```
Temp1: 3.14159265
Temp1: -2.0261201123350516
Temp1: 0.5240439129723575
Temp1: -0.07522061155511761
Temp1: 0.006925274211222368
Temp1: -4.451566418505852E-4
usw...
```

Was kann man den falsch machen? Ich subtrahiere oder addiere jeweils (Num/Denum) vom alten Ergebnis ab/dazu.


----------



## SlaterB (8. Dez 2009)

> Sinus(Pi) soll ja wohl etwas mit 0.05480 ergeben.

na das solltest du in keiner Prüfung dieser Welt behaupten 

Google

Bogenmaß mit Grad verwechselt? selbst da kommt aber ein Wert nahe 0 raus


----------



## DerPeter (8. Dez 2009)

Gut, dann soll mir null auch recht sein =)

Temp 1 hat also z.B. den Wert "3.5897928558855484E-9"
was soviel bedeutet wie 0,0000000003589.......

Wenn ich versuche


```
tempEps = temp2-temp1
```

zu machen, dann bricht das programm beim 2ten durchlauf schon ab.

aber damit berechne ich doch die differenz vom vorgänger und nachfolger wert und wenn sie kleiner EPS ist?... :shock:


----------



## SlaterB (8. Dez 2009)

bei 
System.out.println(Math.sin(Math.toRadians(3.1415)));
kommt übrigens 0.05480 raus, na das ist schon recht nahe

temp2-temp1 rechnest du hoffentlich nicht direkt nach der Zeile temp2 = temp1;
?
kompletter Code wäre hilfreich


----------



## DerPeter (8. Dez 2009)

Wie gesagt ich rehcne gar nicht tempEps = temp2-temp1 weil wenn ich das so mache,dann bricht er nach 2 runden schon ab.


```
public class Sinus {

		public static void main(String[] args) {
			
			System.out.println(getSin(3.14159265,1E-10));

	}
		
		public static double getSin(double x, double eps){
			// Variablen instanziieren
			double result;
			double vorzeichen = -1;
			double tempEps = 0.0;
			
			double temp1 = 0.0;
			double temp2 = 0.0;			
						
			double num = x;
			double denum = 1.0;	
			
			int i = 1;
			int n = 1;
			
			int faki = 1;
			int fakn = 1;
			
								
			while (tempEps <= eps) {
				
				
				vorzeichen *= -1;
				temp2 = temp1;
								
				System.out.print(num);
	

				while (faki<=fakn){
					denum *= faki;
					faki++;
				}
				
				System.out.print("/"+denum+"\n");
				
				temp1 += vorzeichen*(num/denum);
				System.out.println("Temp1: "+temp1);
				
				tempEps -= temp1;

				//if (tempEps<0.0){tempEps*=-1;}
				
				System.out.println("TempEps: "+tempEps);
				
				//System.out.println("Temp2: "+temp2);
				num *= (x*x);

				fakn += 2;
				faki = 1;
				denum = 1.0;
								
			}
			
			
			return temp1;
		}

}
```


----------



## SlaterB (8. Dez 2009)

o, die Bedingung ist auch nicht so schön, 
wenn tempEps 4500 ist, also größer als eps, dann wird abgebrochen, dass soll so wohl nicht sein,

und auch negative Werte bedenken, eps 0.1 bedeutet einen Bereich von -0.1 bis +0.1, 
also tempEps -0.04 oder + 0.04 akzeptieren,
aber tempEps -2 oder + 2 nicht akzeptieren,


----------



## DerPeter (8. Dez 2009)

Demnach wäre es so korrekt? So funktioniert theoretisch alles...
Zumindest bricht er ab bei


```
3.5896222372708693E-9
```


```
public class Sinus {

		public static void main(String[] args) {
			
			System.out.println(getSin(3.14159265,1E-10));

	}
		
		public static double getSin(double x, double eps){
			// Variablen instanziieren
			double vorzeichen = -1;
			double tempEps = 0.0;
			
			double temp1 = 0.0;
			double temp2 = 0.0;			
						
			double num = x;
			double denum = 1.0;	
			
			
			int faki = 1;
			int fakn = 1;
			boolean abbruch = false;
			
								
			while (!abbruch) {
				
				
				vorzeichen *= -1;
				temp2 = temp1;
								
				//System.out.print(num);
	

				while (faki<=fakn){
					denum *= faki;
					faki++;
				}
				
				//System.out.print("/"+denum+"\n");
				
				temp1 += vorzeichen*(num/denum);
				//System.out.println("Temp1: "+temp1);
				
				tempEps = temp2-temp1;

				if (tempEps<0.0){tempEps*=-1;}
				
				//System.out.println("TempEps: "+tempEps);
				
				//System.out.println("Temp2: "+temp2);
				num *= (x*x);

				fakn += 2;
				faki = 1;
				denum = 1.0;
				
				if (tempEps <= eps)
					 abbruch = true;
								
			}
			
			
			return temp1;
		}

}
```


----------



## SlaterB (8. Dez 2009)

sieht besser aus, über vollständige Korrektheit möchte ich nicht entscheiden,
boolean abbruch ist recht deutlich, geht aber auch ohne,

while(tempEps > eps)
wäre die äquivalent Bedingung


----------

