Doppelfakultät?
-
Hi leute!
Ich möchte gerade die ungerade Doppelfakultät (also 1! 3! 5! 7! usw) programmieren. Diese ist ja definiert mit: (2k-1)!!.
Mein Vorschlag: n = n*(n+1)*(n+2);
Ich hab grad überhaupt keine Ahnung wie ich das in meinem Programm code umsetzen soll. Könnt ihr mir ein bisschen drauf helfen?
-
Ich hab mal gegooglet, von was du überhaupt redest und gleich die ersten Treffer sind Videos zur Herleitung. Bei dem Video was ich mir angesehen habe, wird von der einfachen Fakultät ausgegangen. Da die ja Standardbeispiel ist, sollte das Problem damit sich lösen lassen.
-
Also die Doppelfakultät ist so definiert:
n gerade: n!! := n * (n-2) * (n-4) * ... * 2
n ungerade: n!! := n * (n-2) * (n-4) * ... * 10!! := 1
-1!! := 1Ist also eigentlich genau das gleiche wie Fakultät, ausser dass halt immer nur gerade bzw. ungerade Faktoren verwendet werden bei der Multiplikation.
Du kannst dann ja mal in einer for-Schleife die normale Fakultät programmieren. Für die Doppelfakultät musst du dann halt statt Schrittgrösse 1 die Schrittgrösse 2 wählen. (Eventuell ist dann eine while-loop fast besser geeignet).
-
icarus2 schrieb:
Für die Doppelfakultät musst du dann halt statt Schrittgrösse 1 die Schrittgrösse 2 wählen. (Eventuell ist dann eine while-loop fast besser geeignet).
-
mngbd schrieb:
icarus2 schrieb:
Für die Doppelfakultät musst du dann halt statt Schrittgrösse 1 die Schrittgrösse 2 wählen. (Eventuell ist dann eine while-loop fast besser geeignet).
Ja mit Schrittgrösse meine ich folgendes:
n! = n * (n-1) * (n-2)...
Wenn man das in einer for-Schleife macht inkrementiert/dekrementiert man ja immer um 1. Bei der Doppelfakultät könnte man dann um 2 inkrementieren/dekrementieren (habs gestern kurz ausprobiert).
Vielleicht ist Schrittgrösse nicht gerade das beste Wort, aber mir ist nix bessers dafür eingefallen ^^*Edit
Ja, den teil mit der while-loop kann man streichen ^^
-
icarus2 schrieb:
Wenn man das in einer for-Schleife macht inkrementiert/dekrementiert man ja immer um 1.
Huh? Wie kommst du darauf? Alle drei Felder des for-Headers kannst du wählen wie es dir beliebt. Inklusive leerer Anweisungen und Verkettungen mittels Kommaoperators. Gegenüber solchen Tricksereien ist ein simples
i+=2
doch harmlos.
-
SeppJ schrieb:
icarus2 schrieb:
Wenn man das in einer for-Schleife macht inkrementiert/dekrementiert man ja immer um 1.
Huh? Wie kommst du darauf? Alle drei Felder des for-Headers kannst du wählen wie es dir beliebt. Inklusive leerer Anweisungen und Verkettungen mittels Kommaoperators. Gegenüber solchen Tricksereien ist ein simples
i+=2
doch harmlos.Ich habe hier von der Fakultät gesprochen. Also wie würdest du denn eine iterative Funktion schreiben, die nicht einfach i++ oder i-- in der for-Schleife macht macht?
Dass man sonst natürlich andere Dinge machen kannst ist klar. Habe mich vielleicht schlecht ausgedrückt.
-
icarus2 schrieb:
Ich habe hier von der Fakultät gesprochen. Also wie würdest du denn eine iterative Funktion schreiben, die nicht einfach i++ oder i-- in der for-Schleife macht macht?
Dass man sonst natürlich andere Dinge machen kannst ist klar. Habe mich vielleicht schlecht ausgedrückt.Also irgendwie verstehe ich das Problem nicht.
unsigned long long double_faculty(unsigned N) { unsigned long long result=1; for (unsigned i=2-(N%2); i<= N; i+=2) result*=i; return result; }
P.S.: Ach, jetzt verstehe ich was du meinst. Ok, dann haben wir ohnehin das gleiche gemeint. Du wolltest dem Threadersteller ebenfalls sagen, dass er auch etwas anderes als +1 benutzen kann, ich hatte dich bloß nicht richtig verstanden.
Und der Threadersteller hat das Glück, dass ich ihm gerade ohne jede Eigenleistung die Aufgabe gelöst habe :xmas1:
-
Hey Leute!
Ich meld mich dann auch mal wieder zu Wort. Der Hintergrund des Programm ist, dass ich den sin(x) durch Taylorentwicklung berechen möchte. Mein bisheriges Programm sieht so aus:
#include<stdio.h> int main() { double z, s, si, x, g, n; int i; printf("Berechnung von sin(x) \n"); printf("x = "); scanf("%lf", &x); printf("Genauigkeit g = "); scanf("%lf", &g); printf("\ni Summand Summe\n"); printf("--------------------------------------\n"); z = x; n = 1.0; do { si = z/n; z = z * (x * x); } while(si > g); return 0; }
Da eben beim Sinus im Nenner die ungerade Doppelfakultät benutzt wird, muss ich diese ja auch in der Berechnung des Sinus (in der do-Schleife) implementieren. Das dumme ist nur, dass ich eben nicht eine Doppelfakultät wie z.B. 3! sondern zur Laufzeit der Schleife sich erhöhende ungerade Doppelfakultät brauche. Deswegen verstehe ich grad auch nicht wie ich das dann in meinem Fall mit einer for-Schleife lösen soll!
-
Hier habe ich kurz was gecodet wie das aussehen könnte. Am besten testest du vielleicht die Funktion noch:
long double_factorial( int n ) { long result; // n even? if( n % 2 == 0 ) result = 2; else result = 1; for( int i = result + 2; i <= n; i += 2 ) result *= i; return result; }
*Edit
Hoffe, der Stil ist nicht allzu schlecht ^^*Edit 2
Diese Funktion kann man natürlich für gerade sowie ungerade Doppelfakultät verwenden.
-
bandchef schrieb:
Das dumme ist nur, dass ich eben nicht eine Doppelfakultät wie z.B. 3! sondern zur Laufzeit der Schleife sich erhöhende ungerade Doppelfakultät brauche. Deswegen verstehe ich grad auch nicht wie ich das dann in meinem Fall mit einer for-Schleife lösen soll!
In dem Fall würde ich auf eine Fakultätsfunktion verzichten, und n in jedem Schleifendurchlauf mit dem aktuellen Wert von x multiplizieren.
icarus2 schrieb:
...
Hoffe, der Stil ist nicht allzu schlecht ^^Ich seh da nichts, was man schlechten Stil nennen könnte. Getestet hab ich's aber nicht.
icarus2 schrieb:
Vielleicht ist Schrittgrösse nicht gerade das beste Wort, aber mir ist nix bessers dafür eingefallen ^^
Afaik ist auf Deutsch das Wort "Schrittbreite" am gebräuchlisten.
icarus2 schrieb:
*Edit
Ja, den teil mit der while-loop kann man streichen ^^Ich wollte nicht unhöflich sein, aber das hat mich einen Kurs erinnert, den ich einmal gemacht habe. Dort hat der Vortragende einen leidenschaftlichen philosophischen Monolog darüber gehalten, wann man for und while einsetzen soll. Diejenigen, die dort zum ersten Mal von solchen Schleifen-Konstrukten gehört haben, benehmen sich jetzt folglich bisweilen so, als wäre das eine wichtige Frage, und diskutieren sie leidenschaftlich und in allen Einzelheiten. Ich hab befürchtet, dass du auch damit anfangen willst.
-
icarus2 schrieb:
long double_factorial( int n ) { long result; // n even? if( n % 2 == 0 ) result = 2; else result = 1; for( int i = result + 2; i <= n; i += 2 ) result *= i; return result; }
Wo soll denn hier das Doppel sein? C89 ist es auch nicht.
long double double_factorial_odd( int n ) { long double result=1.0,i; for( i = 3; i <= n; i += 2 ) result *= i*i; return result; }
-
mngbd schrieb:
icarus2 schrieb:
Vielleicht ist Schrittgrösse nicht gerade das beste Wort, aber mir ist nix bessers dafür eingefallen ^^
Afaik ist auf Deutsch das Wort "Schrittbreite" am gebräuchlisten.
Oki, thx für die Info.
mngbd schrieb:
icarus2 schrieb:
*Edit
Ja, den teil mit der while-loop kann man streichen ^^Ich wollte nicht unhöflich sein, aber das hat mich einen Kurs erinnert, den ich einmal gemacht habe. Dort hat der Vortragende einen leidenschaftlichen philosophischen Monolog darüber gehalten, wann man for und while einsetzen soll. Diejenigen, die dort zum ersten Mal von solchen Schleifen-Konstrukten gehört haben, benehmen sich jetzt folglich bisweilen so, als wäre das eine wichtige Frage, und diskutieren sie leidenschaftlich und in allen Einzelheiten. Ich hab befürchtet, dass du auch damit anfangen willst.
Nein, ich wollte keine Diskussion darüber starten
Ich hatte zuerst gedacht, dass man es mit einer for-Schleife nicht so gut lösen kann, musste dann aber feststellen, dass es mit for und while genau gleich gut geht. Darum habe ich noch gesagt, dass er meinen Tipp, die while-Schleife zu benutzen, vergessen soll.
-
@ Wutz:
Ich denke meine Doppelfakultät stimmt, gemäss der Definition auf Wikipedia:
DoppelfakultätJa, ich kann leider kein C89, habe mich bis jetzt nur mit C++ beschäftigt. Obwohl... funktioniert mein Code echt nicht in C89?
-
icarus2 schrieb:
Obwohl... funktioniert mein Code echt nicht in C89?
Nein. Das Deklarieren von Variablen im Kopf von for-Schleifen ist ein ganz typisches C++-Konstrukt.
Und wenn man ganz klugscheißerisch drauf ist, dann gibt es in C89 auch keine Kommentare mit // ..., sondern nur mit /* ... */. Wobei ich hierauf jedoch keine Rücksicht nehmen würde.
-
Achso, danke. Das habe ich nicht gewusst.
-
Hi Leute!
Ich kann euch jetzt mal mein funktionierendes Programm präsentieren:
#include<stdio.h> int main() { double s, si, x, g; double z, i, n, fac, sinus; int zaehler; printf("Berechnung von sin(x) \n"); printf("x = "); scanf("%lf", &x); printf("Genauigkeit g = "); scanf("%lf", &g); printf("\ni Summand Summe\n"); printf("--------------------------------------\n"); z = x; n = 1; fac = 1; sinus = 0; zaehler = 0; do { si = z / fac; z = z * (x * x); n = n + 2; fac = 1; for(i=1; i<=n; i=i+1) { fac = fac * i; } if(zaehler % 2 == 0) { sinus = sinus + si; } else { sinus = sinus - si; } zaehler = zaehler + 1; } while(si > g); printf("%lf", sinus); return 0; }
Wenn's was zum Aussetzen gibt, dann sagt es mir; ich mein so schlechter Stil, oder so...
-
Bei
if(zaehler % 2 == 0)
würde ich eine Klammer spendieren, "lf" bei printf ist nicht C89, Rückgabewerte von scanf wertest du nicht aus, Eingabepuffer leerst du danach nicht (wenn du mal erweitern und was anderes als Zahlenwerte liest... macht sich dies unangenehm bemerkbar und steigert deine Verwirrung), ich würde mal sagen Schulnote 3.
-
... Rückgabewerte von scanf wertest du nicht aus, Eingabepuffer leerst du danach nicht ...
Von diesen beiden Sachen hab ich noch nie was gehört. Kannst du mir erklären, was ich da machen soll? Die Klammer hab ich mittlerweile rangemacht.