mathematisches und programmiertechnisches Problem- Fakultät einer Zahl
-
int main () { long zahl, ergebnis = 1; cout << "Zahl: "; cin>>zahl; for (long i=zahl; i >1 ; i--) ergebnis *= i; cout << endl << "Ergebnis: " << ergebnis << endl; return 0; }
so, aber ich habs net getestet, nur so hingeschmiert
-
Ich würde das mit einer Rekursion lösen. Um dir nicht alles zu verraten, hier ein Ansatz:
fakultät von x im folgenden als f(x) f(1)=1 f(2)=1*2 f(3)=1*2*3 f(4)=1*2*3*4 f(5)=1*2*3*4*5 f(6)=1*2*3*4*5*6 f(7)=1*2*3*4*5*6*7 f(8)=1*2*3*4*5*6*7*8 f(9)=1*2*3*4*5*6*7*8*9
Klingelts? Falls dir Rekursionen unbekannt sind:
Abstrakt: Eine Rekursion ist eine selbstaufrufende Funktion mit mindestens einer Abbruchbedingung.
Konkret: Eine Rekursion erwartet mindestens eine Eingabe. Dann testet sie, ob die Eingabe der Abbruchbedingung entspricht. Wenn nicht, ruft sie sich selbst mit einer von der Eingabe abgeleiteten Eingabe auf, und macht mit dem Ergebnis was. Bsp. (Pseudocode):func rektest(int eingabe) if eingabe=0 then return 1 else return rektest(eingabe-1)*2
Versuche, die Aufgabe rekursiv zu formulieren. Tipp: Abbruchbedingung siehe 1. Rechnung.
Achja: du kannst das ganze auch iterativ lösen, ich finde aber rekursionen Verständlicher (in diesem Fall, aber ich bin allgemein fan von)
Zu deinem code: Du solltest daran denken, das du innerhalb der Schleife einfach eine variable definieren kannst, da sie in den geschweiften Klammern lokal ist, sie wird am Ende der Schleife gelöscht.
Außerdem: es heißt (meistens) int main() und #include <iostream> gefolgt von using namespace std;
/edit: wieder zu langsam
-
Hi !
Erstmal danke für die schnellen Antworten.
Insbesondere NooBie's Vorschlag war für mich als Anfänger sehr gut nachvollziehbar und hat auch super geklappt.
Aber auch die anderen Vorschläge waren interessant; werde ich mir morgen nochmal genauer ansehen.Also nochmals danke und Grüße.
-
@MaSTaH: Deine iterative Variante liefert glaube ich immer 0, da mit n=1 nochmal in die Schleife gegangen wird => n=0, also ist das Produkt 0 und damit die ganze Arbeit im Arsch.
-
Args, blöder Flüchtigkeitsfehler
. Habs rauseditiert. Die Rekursive sollte trotzdem stimmen.
-
Walli schrieb:
// Rekursiv ginge es so unsigned fac(unsigned n) { return n ? 1 : n * fac(n-1); }
Kann mir mal jemand erklären was (ich nehm einfach mal an es ist eine Abfrage) da passiert!? Das mit der Fakultät versteh ich nur nich, wie das hier abläuft <-- noobie
-
template<int n> class Factorial { public: enum { value = n * Factorial<n -1>::value }; }; template<> class Factorial<0> { public: enum { value = 1 }; };
mfg
-
Was hat Template Meta Programming mit der Erklärung zu tun?
@p-chan
Ich vermute mal, du verstehst den trinären Operator ?: nicht. Du kannst die Funktion auch wie folgt schreibenunsigned fac(unsigned n) { if (n) return 1; else return n * fac(n-1); }
Ist exakt die gleiche Logik. Auch wenn mir scheint, dass diese Logik nicht korrekt ist.
-
groovemaster schrieb:
Was hat Template Meta Programming mit der Erklärung zu tun?
ich wollte ihm bloß noch einmal eine andere Möglichkeit zeigen, die weder angesprochen noch explizit gezeigt wurde.
mfg
-
Walli schrieb:
// Rekursiv ginge es so unsigned fac(unsigned n) { return n ? 1 : n * fac(n-1); }
irgendwie verdreht das ganze, oder ?
// Rekursiv ginge es so unsigned fac(unsigned n) { return n ? n * fac(n-1) : 1; }
oder eben iterativ
unsigned fac(unsigned n) { unsigned result = 1; for( unsigned i = 2; i <= n; ++i ) result *= i; return result; }
-
Walli schrieb:
Args, blöder Flüchtigkeitsfehler
. Habs rauseditiert. Die Rekursive sollte trotzdem stimmen.
Nein. Schon wieder ein Flüchtigkeitsfehler
-
warum so kompiliert? Man muss doch nur jeweils den nächsten wert draufaddieren:
int zahl = 5; int counter = 1; int buffer = 0; while (counter <= zahl) { buffer+=counter; counter++; }
-
fluxy schrieb:
warum so kompiliert? Man muss doch nur jeweils den nächsten wert draufaddieren:
int zahl = 5; int counter = 1; int buffer = 0; while (counter <= zahl) { buffer+=counter; counter++; }
Quark. camper hat bereits die rek. und it. Version gepostet.
-
terraner schrieb:
ich wollte ihm bloß noch einmal eine andere Möglichkeit zeigen, die weder angesprochen noch explizit gezeigt wurde.
Und das zurecht. Immerhin hat der Threadersteller keinen Eingabewert, der zur Compilezeit evaluiert werden kann.
Ausserdem glaube ich nicht, dass jemand, der "iostream.h" benutzt und 'void main' schreibt, schon für Template Meta Programming bereit ist. Trotzdem danke, dass du uns an deinem Wissen teilhaben lassen hast.
-
groovemaster schrieb:
Und das zurecht. Immerhin hat der Threadersteller keinen Eingabewert, der zur Compilezeit evaluiert werden kann.
upps... *blind*
Ausserdem glaube ich nicht, dass jemand, der "iostream.h" benutzt und 'void main' schreibt, schon für Template Meta Programming bereit ist. Trotzdem danke, dass du uns an deinem Wissen teilhaben lassen hast.
falls mal jemand mal ein ähnliches problem hat und diesen thread sucht, möchte ich eben, dass er diesen source-code inklusive meinem in stein dazugemeißelten namen sieht...
mfg
-
also wir haben uns mit der Fakultät auch in der schule beschäftigt, leider klappt das programm nur bis 12! Danach, also ab 13! sind die Werte fehlerhaft; unser Lehrer meinte irgendwie, das für long int nur 4 Byte reserviert sind und das deshalb nich klappt. Wie kann man nun also größere Fakultäten berechnen???
-
Du kannst als Datentyp double nehmen oder naja ... eigener Datentyp ... das wars dann :p
-
je nach Plattform ginge auch noch unsigned long long. Mit dem vc7.1 oder dem gcc bekommt man so einen 64Bit unsigned. Der reicht auch ganz schön weit.
MfG Jester
-
vielleicht sollte man erwähnen, daß man in diesem Falle eine iterative Lösung bevorzugen sollte. ist klar, oder?!
-
Könnte mir das jemand aufschreiben, wie man solch einen neuen Datentyp erstellt?... natürlich nur, wenn es nicht allzu aufwendig ist