mal wieder c... berechnung binominalkoeffizienten

Registriert
14. März 2002
Reaktionspunkte
2
Ort
Reutlingen
folgendes prog soll den binominalkoeffizienten berechnen. mit diesem lässt sich zum beispiel die wahrscheinlichkeit berechnen, einen 6er bei 6 aus 49 zu bekommen.

allerdings funktioniert das prog nicht so wie ich es gern hätte. :(

formel für den binominalk. : menge!/(elemente!*(menge-elemente)!)

mit kleinen zahlen funktioniert das ganze, sobald ich aber grössere zahlen eingebe, kommt irgend ein murks raus... dachte schon, das die datentypen falsch gewählt sind, aber das kann ja net sein bei float... jemand ne idee?

Code:
float binominal (int b_element, int b_menge);
float fakultaet (int zahl);
void main ()
{
int menge, elemente;
float ergebniss;
 
printf("Eingabe der Menge: \t");
scanf("%d", &menge);
 
printf("Eingabe der Elemente: \t");
scanf("%d", &elemente);
ergebniss = binominal(elemente, menge);
printf("Anzahl der Kombinationsmöglichkeiten: \t%.0f\n", ergebniss);
}
float binominal (int b_elemente, int b_menge)
{
float b_ergebniss = 1;
b_ergebniss = fakultaet(b_menge)/(fakultaet(b_elemente)*fakultaet((b_menge-b_elemente)));
 
return b_ergebniss;
}
float fakultaet (int zahl)
{
float f_ergeb=1;		 
for(int i=zahl; i>0; i--)	 
{			
f_ergeb = f_ergeb * i;	 
}			
return f_ergeb;		 
}
 
derschotte schrieb:
folgendes prog soll den binominalkoeffizienten berechnen
[...]
mit kleinen zahlen funktioniert das ganze, sobald ich aber grössere zahlen eingebe, kommt irgend ein murks raus... dachte schon, das die datentypen falsch gewählt sind, aber das kann ja net sein bei float... jemand ne idee?

float ist zu ungenau (zu wenig signifikante Stellen in der Mantisse), versuch's mal mit long double.

Daniel
 
derschotte schrieb:
hab ich auch schon versucht... leider ohne erfolg :(

Ein alter gcc 2.7.2.1 liefert hier nach kleiner Modifikation in Form von

Code:
vi gehtnicht.c
:1,$s/float/long double/g
:1,$s/\.0f/.0Lf/g
:wq

wunderbar ein Ergebnis von 13983816 für 49 über 6. Du hast vermutlich schlicht vergessen, den abschließenden printf auf das andere Ausgabeformat für "long double" anzupassen. Oder Dein Compiler gehört auf den Müll.

Daniel
 
schotte .. nachdem Du evtl. immer noch nicht in eine Umgebung umgeschwenkt hast, wo Du mit vi und ex-Commands was anfangen kannst: ;)

Hast Du auch dran gedacht ausser der Definition den Format String beim printf auf den long double anzupassen?
 
Wahrscheinlich hat er jetzt seinen Rechner zerlegt und kann nicht mehr antworten ;)

Unabhängig davon ist eine Implementierung mit Fakultäten ja wohl als -- äh -- nicht sonderlich robust zu bezeichnen. Mindestens mal würde ich den größeren der Divisoren k! und (n-k)! vorher wegkürzen. Eine einfache Möglichkeit, Überläufe zu vermeiden, wäre auch das Pascal-Dreieck.

Genauigkeit: Schon für 150 \choose 75 reicht long double nicht mehr hin -- also lange Ganzzahlen selber implementieren oder besser eine Bibliothek wie gnu gmp, ntl oder wasweissich verwenden oder noch besser auf java umsteigen ;)
 
ist ne schuleaufgabe, in der es darum ging, das ganze mit mehreren funktionen zu realisieren... und das klappt ja :)
freiwillig mach ich sicher kein c.. das is ja wohl die dümmste sprache wo es gibt... :) zumindest was das erlernen angeht...

hab bisher wesentlich weniger probs mit vb gehabt, da dieses doch intuitiver zu bedienen und erlernen ist.. aber wie gesagt, ich werde gezwungen, c zu lernen :D

ps: gut, das hier 3 rechner stehen mit denen ich surfen kann :D
 
derschotte schrieb:
das is ja wohl die dümmste sprache wo es gibt...

Gut erkannt! :D

C tut im Gegensatz zu manchen anderen Sprachen nichts Schlaues automatisch, wenn man mal von Compiler-Optimierungen absieht. Ich halte das jedoch fuer einen Vorteil ;)
 
Zurück