Variable ist zu klein
-
Könnte mir einer mal bitte den Code kommentieren? Die Parameter der Schleife kapier ich nicht ganz...
-
ist (i) größer als der größere von (k) und (n-k)?
-
Ich weiß nicht, wieso "binom" zwei Parameter bekommen soll. Wenn
(a+b)^4
dann ist n=4. k ist am Anfang immer 0. Deshalb braucht das auch nicht angegeben zu werden.
-
Könnte mir einer mal bitte den Code kommentieren? Die Parameter der Schleife kapier ich nicht ganz...
http://www.ica1.uni-stuttgart.de/~hilfer/de/lehre/100-online/skriptum/node34.html
Ich weiß nicht, wieso "binom" zwei Parameter bekommen soll.
binom berechnet n über k und nicht die Fakultät...
-
binom berechnet n über k und nicht die Fakultät...
Für die Fakultät habe ich ja extra eine eigene Funktion geschrieben. binom kriegt nur den einen Parameter n, die Grundform ist ja
(a+b)^n
Das k ist immer gleich, ganz egal wie groß n ist.
Aber danke für den Link!
-
So hatte ich das gedacht:
void binomAnzeigen(unsigned int n) { switch(n) { case 0: cout << "1"; break; case 1: cout << "a + b"; break; case 2: cout << "a^2 + 2ab + b^2"; break; default: unsigned int k; unsigned long x, y; cout << "a^" << n << " + "; for(k=1;k<n;k++) { if(k==1) cout << n << "a^" << (n-1) << "b + "; else { if(k==(n-1)) cout << n << "ab^" << k << " + "; else cout << binom(n,k) << "a^" << (n-k) << "b^" << k << " + "; } } cout << "b^" << k; break; } }
-
Dann hatte ich dich falsch verstanden, fubar.
Jetzt könnte man auch x und y aus binomAnzeigen rauswerfen, um noch ein bisschen Platz zu sparen.
Danke für deine Hilfe!!!
-
mit double sollte es gehen... z.b. so:
double fakDouble(double x)
{
if(x<0)
return 0;
if(x==0)
return 1;
else
return x * (fakDouble(x-1));
}
-
Eine schöne Möglichkeit ist auch sich ne Abschätzung für n über k zu besorgen und dann noch eine Primzahl p, die größer als diese Schranke ist. Mann kann dann nämlich einfach alle Schritte modulo p rechnen, also immer den Rest bezüglich Division durch p. (Mathematiker würden sagen man projiziert auf Z/pZ)
Der Rest liegt dann zwischen 0 und p-1. Weil ja aber das Ergebnis sowieso < p ist, ist dieser Rest gerade das Ergebnis. Auf diese Art und Weise kann man auch noch für ziemlich große n rechnen, weil die Fakultät ja immer wieder mit mod p klein gehalten wird.MfG Jester
-
Ich hab mich grad mal hingesetzt und noch ein bißchen rumgerechnet.
Ohne große Klimmzüge komme ich mit dieser Version wohl bis n=34.MfG Jester
-
Kannste mal Code posten dann wieß ich auch wat du mit Abchätzung meins. Bin net so gut in Mathe.
-
Also ich benutze immer folgende Funktion
template<typename T> T Binomial(unsigned n, unsigned k) { if(k > n) return 0; if(k == n) return 1; T rval = 1; for(unsigned i = n; i != k; --i) rval *= i; for(unsigned i = n - k; i != 1; --i) rval /= i; return rval; }
-
Hab den Code grad nicht greifbar. Kommt heute abend (nacht) irgendwann oder morgen früh.
MfG Jester
-
Man könnte ja auch eine zu große Zahl durch 65535 teilen, den Ganzzahlwert in einer unsigned _int64 und den Rest in einer unsigned int-Variable speichern. Zur Ausgabe mit cout rechnet man dann rückwärts
-
*knock* *knock*. Ich habe doch eine funktionierende Lösung gepostet. Wenn du die so aufrufst...
unsigned long long x = Binomial<unsigned long long>(n, k); unsigned __int64 y = Binomial<unsigned __int64>(n, k);
...dann solltest du relativ hohe Werte erhalten können. Deine Idee mit dem dividieren funktioniert auch nur begrenzt und ist viel aufwändiger (NR sux
).
-
MaSTaH schrieb:
unsigned long long x = Binomial<unsigned long long>(n, k);
unsigned long long funktioniert bei mir nicht
unsigned __int64 y = Binomial<unsigned __int64>(n, k);
Mit der Variante kommst du bis 20!. Wenn du es aber machst, wie ich beschrieben hab (bloß mit zwei unsigned _int64), dann kommt man bis 34!.
(NR sux
).
Was heißt das???
-
Für die Praxis: Einfach logarithmisch rechnen mit double-Werten. Damit kommt man sehr weit!
ln(k!) = Sum(i=1..k){ln(i)}#include <math.h> double LogFak(int k) { double dLogSum = 0; while(k > 1) { dLogSum += log((double) k); --k; } return dLogSum; }
-
#define MERKE_ERSTE 1000 //Zum Beschleunigen die ersten paar Werte merken double LogFak(int k) { static int siValid = 1; //Index, bis zu dem Array-Inhalt gueltig ist static double sadLogFak[MERKE_ERSTE] = { 0 }; if(k <= siValid) return sadLogFak[k]; double dLogSum = saLogFak[siValid]; int i = siValid + 1; while(i < MERKE_ERSTE) { dLogSum += log((double) i); sadLogFak[i] = dLogSum; ++i; } siValid = i - 1; while(i <= k) { dLogSum += log((double) i); ++i; } return dLogSum; }
-
Sorry, kann noch keinen Logarithmus. Kannst du mir mal zeigen, was ich mit dem return-Wert anfangen soll und wieso der return-Wert bei 1 bis 999 gleich ist (wenn #define MAX_WERT 10000, dann sind sogar alle return-Werte bis 9999 gleich)
.
-
CME386 schrieb:
unsigned long long funktioniert bei mir nicht
Kann auch nicht jeder Compiler. Nur gcc, VC++ (>7)...
CME386 schrieb:
Mit der Variante kommst du bis 20!. Wenn du es aber machst, wie ich beschrieben hab (bloß mit zwei unsigned _int64), dann kommt man bis 34!
Wieso Fakultät? Ich denke du willst 'nen Binomialkoeffizienten? Meine Variante kürzt schon vor dem berechnen des Bruches.
CME386 schrieb:
Was heißt das???
"Neue Rechtschreibung" (NR) suckt. -> wg. aufwändig