Ich glaub die bisherigen Vorschläge sind vielleicht nicht optimal, da spätestens bei 47/31 so merkwürdige Brüche rauskommen wie: 1516129/1000000
Ich hab' da mal meine Phantasie spielen lassen und mir einen rekursiven Algorithmus aus den Fingern gesaugt:
Delphi-Quellcode:
procedure DezToBruch(DezimalZahl:double;var Zaehler,Nenner:integer;Tiefe:integer);
const ZuKlein=1E-6;
Winzig=1E-12;
var GanzAnteil,a,b:integer;
begin
GanzAnteil:=trunc(DezimalZahl+Winzig);
if (Tiefe>1) and (abs(DezimalZahl-GanzAnteil)>ZuKlein) then begin
DezToBruch(1/(DezimalZahl-GanzAnteil),a,b,Tiefe-1);
Zaehler:=a*GanzAnteil+b;
Nenner:=a;
end else begin
Zaehler:=GanzAnteil;
Nenner:=1;
end;
end;
Ich hätte den Algorithmus gerne an einem Beispiel erklärt, bin aber zu faul dafür. Deswegen lasse ich den Algorithmus sich von selbst erklären.
Einfaches Beispiel: 7/3=2.33333333
DezToBruch(2.33333333,Zaehler,Nenner,20);
Der ganzzahlige Anteil von 2.33333333 ist 2
Nach dem Komma bleibt also 0.33333333 übrig
Der Kehrwert davon ist 3.00000000, den wir versuchen als Bruch darzustellen
-----Der ganzzahlige Anteil von 3.00000000 ist 3
-----Nach dem Komma bleibt nicht viel übrig, also erhalten wir 3/1
Dabei kommt also 3/1 raus
Da das ja ein Kehrwert war, entspricht das 1/3
Mit der 2 vor dem Komma sind das zusammen 7/3
Kompliziertes Beispiel: 47/31=1.51612903
DezToBruch(1.51612903,Zaehler,Nenner,20);
Der ganzzahlige Anteil von 1.51612903 ist 1
Nach dem Komma bleibt also 0.51612903 übrig
Der Kehrwert davon ist 1.93750000, den wir versuchen als Bruch darzustellen
-----Der ganzzahlige Anteil von 1.93750000 ist 1
-----Nach dem Komma bleibt also 0.93750000 übrig
-----Der Kehrwert davon ist 1.06666667, den wir versuchen als Bruch darzustellen
----------Der ganzzahlige Anteil von 1.06666667 ist 1
----------Nach dem Komma bleibt also 0.06666667 übrig
----------Der Kehrwert davon ist 15.00000000, den wir versuchen als Bruch darzustellen
---------------Der ganzzahlige Anteil von 15.00000000 ist 15
---------------Nach dem Komma bleibt nicht viel übrig, also erhalten wir 15/1
----------Dabei kommt also 15/1 raus
----------Da das ja ein Kehrwert war, entspricht das 1/15
----------Mit der 1 vor dem Komma sind das zusammen 16/15
-----Dabei kommt also 16/15 raus
-----Da das ja ein Kehrwert war, entspricht das 15/16
-----Mit der 1 vor dem Komma sind das zusammen 31/16
Dabei kommt also 31/16 raus
Da das ja ein Kehrwert war, entspricht das 16/31
Mit der 1 vor dem Komma sind das zusammen 47/31
Hier ist nochmal der Algorithmus mit Selbsterklärungs-Funktion:
Delphi-Quellcode:
procedure DezToBruch(DezimalZahl:double;var Zaehler,Nenner:integer;Tiefe:integer);
const ZuKlein=1E-6;
Winzig=1E-12;
var GanzAnteil,a,b:integer;
s:string;
begin
GanzAnteil:=trunc(DezimalZahl+Winzig);
s:=DupeString('-----',20-Tiefe);
TextAusgabe(s+'Der ganzzahlige Anteil von '+FloatToStrF(DezimalZahl,ffFixed,12,8)+' ist '+InttoStr(GanzAnteil));
if (Tiefe>1) and (abs(DezimalZahl-GanzAnteil)>ZuKlein) then begin
TextAusgabe(s+'Nach dem Komma bleibt also '+FloatToStrF(DezimalZahl-GanzAnteil,ffFixed,12,8)+' übrig');
TextAusgabe(s+'Der Kehrwert davon ist '+FloatToStrF(1/(DezimalZahl-GanzAnteil+Winzig),ffFixed,12,8)+', den wir versuchen als Bruch darzustellen');
DezToBruch(1/(DezimalZahl-GanzAnteil),a,b,Tiefe-1);
TextAusgabe(s+'Dabei kommt also '+inttostr(a)+'/'+inttostr(b)+' raus');
TextAusgabe(s+'Da das ja ein Kehrwert war, entspricht das '+inttostr(b)+'/'+inttostr(a));
Zaehler:=a*GanzAnteil+b;
Nenner:=a;
TextAusgabe(s+'Mit der '+InttoStr(GanzAnteil)+' vor dem Komma sind das zusammen '+inttostr(zaehler)+'/'+inttostr(nenner));
end else begin
TextAusgabe(s+'Nach dem Komma bleibt nicht viel übrig, also erhalten wir '+IntToStr(GanzAnteil)+'/1');
Zaehler:=GanzAnteil;
Nenner:=1;
end;
end;
Hoffe, ich konnte helfen,
Micho
_________________
www.michael-kreil.de