Eulersche Zahl

Hallo alle miteinander,

ich bin ein total Neuling was Programmieren angeht. Ich komme bei einer Schulaufgabe irgendwie nicht weiter.

Wir sollen ein Programm schreiben das die Eulersche darstellt. Diese lässt sich ja als Reihe Darstellen. Also die Summe von 0 bis unendlich von 1/n!

Meine Aufgabe ist es nun die ersten 50 summen zu ermitteln.

Habe folgendes Programm geschrieben, aber leider macht es gar nichts und ich weiß nicht warum :frowning:

Bitte hier um keine Lösung, lediglich kleinen Denkanstoss bzw. zeigen warum mein Algorithmus nicht funktioniert.


	public static void main(String[] args) {
		 
				double e = 1;
				double summe = 1;
				int k = 1;
				double n = 1;
				
			    while(k<50);
			    {
			    	n = n*k;
			    	summe = 1 / n;
			    	e = e + summe;
			    	k++;
			    	System.out.println(summe); //Ausgabe der Einzelnen Partialsummen
			    }
				System.out.println(e);

	}

}```

Danke und Gruß Drummy

gar nicht schlecht,
nur das Semikolon in while(k<50); weg, dann funktioniert es,

gemein von Java, so ein Konstrukt zuzulassen, Endlosschleife mit leerer Anweisung, CPU (ein Kern) auf 100%,
achte darauf ob das vielleicht noch in irgendeiner Version läuft, evtl. Neustart Computer

eine IDE wie Eclipse dürfte dir das je nach Einstellungen als Warnung anzeigen

allgemein zum Testen besser mit 5 statt 50 anfangen, spielt hier beim Fehler aber keine Rolle

ach und summe ist kein guter Variablenname, ist ja keine Summe :wink: , die Summe ist hier e

Danke… jetzt gehts…
Das ist echt gemein, da achte ich immer darauf das ich das Semikolon nicht vergessen und jetzt ist es überflüssig:twisted:

Vielen Dank nochmal

Kürzere Variante:

double e = 1;
double q = 1;
for(int i = 1; i < 50; i++) {
  q = q / i;  // oder kürzer: q /= i;
  e = e + q;  // oder kürzer: e += q;
}
System.out.println(e);

[QUOTE=Landei]Kürzere Variante:

double e = 1;
double q = 1;
for(int i = 1; i < 50; i++) {
  q = q / i;  // oder kürzer: q /= i;
  e = e + q;  // oder kürzer: e += i;
}
System.out.println(e);
```[/QUOTE]

Da hat sich ein Flüchtigkeitsfehler in den Kommentar eingeschlichen. Du meinst sicher ` // oder kürzer: e += q;`.

Ich hab mir den Wiki -Artikel durchgelesen. Steht da denn nicht etwas von Fakultät?

        for (int j = 0; j < 50 + 2; j++) {
            double e = 1;
            double q = 1;
            for (int i = 1; i < j; i++) {
                q = q / i;  // oder kürzer: q /= i;
                if (q <= 0) {
                    break a;
                }
                e = e + q;  // oder kürzer: e += q;
            }
            System.out.printf("i=%d, e=%s, q=%s%n", j - 1, e, q);
        }```

OK, 1/2 mal Kehrwert von 3/1 ist auch 1/6. Danke tschö. (Die eigene Dummheit ist alt nicht zu schlagen)

Noch als Anmerkung:

    System.out.printf("i=%03d, e=%-23s, q=%-23s%n", j - 1, e, q);
}
System.out.printf("i=%03d, e=%-23s, q=%-23s%n", 178, Math.E, 0D);
System.out.println(1.0 + 1 - 1 + 1 - 1 + 2 - 1 - 1 + 3 - 2 - 1);``` <-> bessere ausgabe

Also geschrieben ist das ja, 1+1+1/2+1/(23)+1/(64)+1/(24*5)+… oder 1+1+1/2+(1/2)/3+(1/6)/4+(1/24)/5+…
oder 1/((n-1)/n)^n, aber was ist dann 1/((n-1)/n)^n , kann man diesen Bruch umdrehen? (Termumformungen?) (limes)
Die Nachkommastellen der Partialsummen werden ja sehr schnell sehr klein.
Addition ist, glaub’ ich, “nicht so gut” wie Multiplikation oder Division.
Unregistered/Unreg oder/bzw./resp. UnregisteredEee (e triple e) war ich.
Grüße an die Mathefraktion.

Wenn ich wirklich e mit enormer Genauigkeit brauchte, würde ich ausnutzen, dass es (im Gegensatz zu pi) eine regelmäßige Kettenbruchentwicklung hat: [2;1,2,1,1,4,1,1,6,1,1,8,1…]. Damit kann man leicht und relativ schnell den Zähler und Nenner des gewünschten Nährungsbruchs berechnen (natürlich mit BigInteger).

An BigInteger hatte ich jetzt auch schon gedacht, dann “e” zB immer mal 100 nehmen, bevor addiert wird. "Ganzzahl"division gäbe es dann aber doch auch.
So eine Genauigkeit bräuchte man aber nicht, Euler hat, wenn ich das richtig verstanden hab, auch nur 20 Nachkommastellen ausgerechnet, welche Math.E; ja auch nicht hat.

So, jetzt wurden oben ja zwei Varianten gegenübergestellt. Man müsst sagen, ob 1 / i (bzw. n) oder f(q) = f(q-1) / i; bzw. f(q+1) = f(q) / i; jetzt genauer ist.

Liest du überhaupt, was ich schreibe? Die Version mit dem Kettenbruch ist definitiv besser als irgendwelches double- (oder BigDecimal-) Aufsummieren: Integer-Operationen sind exakt, und am Ende wird eine einzige Division ausgeführt.

public static BigDecimal contFracE() {
        BigInteger p_2 = BigInteger.ZERO;
        BigInteger p_1 = BigInteger.ONE;
        BigInteger q_2 = BigInteger.ONE;
        BigInteger q_1 = BigInteger.ZERO;

        for(int i = 0; i < 50; i++) {
            int a = (i % 3 == 2) ?  2*((i+1)/3) : 1;
            if (i == 0) {
                a = 2;
            }
            BigInteger p = p_1.multiply(BigInteger.valueOf(a)).add(p_2);
            BigInteger q = q_1.multiply(BigInteger.valueOf(a)).add(q_2);
            p_2 = p_1;
            p_1 = p;
            q_2 = q_1;
            q_1 = q;
        }
        return new BigDecimal(p_1, 50).divide(new BigDecimal(q_1, 50), BigDecimal.ROUND_HALF_DOWN);
}

Das stimmt z.B. bis auf die letzten 5 Stellen, und man kann es beliebig genau machen, ohne dass sich Rundungsfehler aufschaukeln. Kannst du bitte versuchen, das nachzuvollziehen, anstatt hier wenig zielführend über double-Genauigkeiten zu schwadronieren? Eventuell lernst du ja auch etwas dabei.

Approximation von Kettenbrüchen: http://de.wikipedia.org/wiki/Kettenbruch#Endliche_Kettenbr.C3.BCche_und_ihre_N.C3.A4herungsbr.C3.BCche
Darstellung von e ist wie gesagt [2;1,2,1,1,4,1,1,6,1,1,8,1…], in der Schleife geht a die entsprechenden Werte durch.

Na gut, ich bin in Mathe nicht so gut. Je nach Tagesform kann man ja viel lesen, wenig lesen, langsam lesen und schnell lesen, es kommt immer darauf an, wie man das betrachtet. Aber Gegenfrage, gehst du zu Einladungen überhaupt noch hin? Ich werd’s versuchen, es nachher noch mal zu lesen. Grüße. &et thx.