![]() |
Re: Zahl als Bruch speichern
Hallo alzaimar,
Wie kommst du zu dem Schluss? GGT, KGV und auch REG sollen auch von aussen zur Verfügung stehen. Ich kann mir schon vorstellen dass man GGT und KGV und reg (kürzen) auch noch für andere Zwecke brauchen kann (Primzahlenberechnung oder ähnliches). Im übrigen hab ich vergessen bei der Division und Multiplikation zu kürzen (reg). Wer die Unit benützt bitte nachtragen. Grüsse Rainer |
Re: Zahl als Bruch speichern
Hallo,
hab das Kürzen bei mul und div eingebaut! Grüsse Rainer |
Re: Zahl als Bruch speichern
Zitat:
Die Funktion 'Kürzen' wird nun wirklich nicht außerhalb benötigt, da Du das ja nach jeder Operation ohnehin durchführst. |
Re: Zahl als Bruch speichern
Hallo alzaimar,
jetzt versteh ich! Im Allgemeinen hast du recht. Man sollte KGV und GGT aus der Klasse Tbruch nehmen und als unabhängige Prozeduren deklarieren. Grüsse Rainer |
Re: Zahl als Bruch speichern
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
hier nocheinmal der korrigierte und verbesserte Code:
Delphi-Quellcode:
Grüsse
unit U_bruchrechnen;
interface Type Bruchtyp=packed record z,n: int64; // Int64 bei sehr großen Zahlen end; TBruch = class(TObject) function red(b0,b1:int64):Bruchtyp; function add(b0,b1: Bruchtyp):Bruchtyp; function sub(b0,b1: Bruchtyp):Bruchtyp; function mul(b0,b1: Bruchtyp):Bruchtyp; function divide(b0,b1: Bruchtyp):Bruchtyp; end; function kgv(b0,b1:int64):int64; function ggt(b0,b1:int64):int64; implementation function kgv(b0,b1:int64):int64; Begin result:=b0*b1 div ggt(b0,b1); End; function ggt(b0,b1:int64):int64; var a,b,r:integer; Begin If b0>b1 then Begin a:=b0; b:=b1 end else begin b:=b0; a:=b1; end; // Berechnung des ggt repeat r:= a mod b; a:=b; b:=r until (r=0); result:=a; End; function TBruch.add(b0,b1: Bruchtyp):Bruchtyp; var a:integer;b:bruchtyp; Begin a:=kgv(b0.n,b1.n); b.n:=a; b.z:=(a div b0.n)*b0.z+(a div b1.n)*b1.z; result:=red(b.z,b.n); End; function TBruch.sub(b0,b1: Bruchtyp):Bruchtyp; var a:integer;b:bruchtyp; Begin a:=kgv(b0.n,b1.n); b.n:=a; b.z:=(a div b0.n)*b0.z-(a div b1.n)*b1.z; result:=red(b.z,b.n); End; function TBruch.mul(b0,b1: Bruchtyp):Bruchtyp; Begin result:=red(b0.z*b1.z,b0.n*b1.n); End; function TBruch.divide(b0,b1: Bruchtyp):Bruchtyp; // div geht nicht, weil das ja ein geschützter begriff ist... Begin result:=red(b0.z*b1.n,b0.n*b1.z); End; function TBruch.red(b0,b1:int64):Bruchtyp; var a,a0,a1:integer; Begin a0:=b0;a1:=b1; while ggt(a0,a1)<>1 do Begin a:=ggt(a0,a1); a0:=a0 div a; a1:=a1 div a; End; result.z:=a0; result.n:=a1; End; end. Rainer PS: Bevor die nächsten meckern; man kann GGT und KGV natürlich auch in eine andere Unit packen. Hat mit Bruchrechnung nur mittelbar was zu tun. |
Re: Zahl als Bruch speichern
@ws1976
Ich schlage folgende Änderungen vor In der Funktion ggt sollten die lokalen Variablen den Typ Int64 haben. Warum?: Weils sonst falsche Ergebnisse bringt, wenn nur einer der Parameter > maxint ist. in der Funktion kgv sollte nicht stehen result:=b0*b1 div ggt(b0,b1); sondern result:=b0 div ggt(b0,b1) * b1; Warum?: Weils sonst falsche Ergebnisse gibt, wenn b0*b1 > High(int64) ist. Das ist zwar auch bei der geänderten Variante nicht ausgeschlossen, tritt aber erst bei deutlich höheren Werten auf. |
Re: Zahl als Bruch speichern
Bist Du dir sicher, das a*b div c identisch mit (b div c)*a ist?
Beispiel : a=3, b=4, c=3. (a*b) div c a*b = 12 div 3 = 4 (b div c)*a 4 div 3 = 1 * 3 = 3 |
Re: Zahl als Bruch speichern
Zitat:
Nein, im Gegenteil. Ich bin mir, so wie auch du, sicher daß "a*b div c" nicht identisch ist mit "b div c * a", und ich bin auch sicher daß die Konstrukte i.d.R. unterschiedliche Resultate bringen. Ich bin mir aber sehr sicher, daß die Konstrukte identische Ergebnisse bringen, wenn c ein "GGT" von a und b ist, und das ist bei dem diskutierten Code der Fall. Der Vorteil der letztgenannten Konstruktion ist, daß sie höhere Werte verarbeiten kann. Stell dir vor a und b seien beide 9999999999 (also > maxint), dann wird bei der vorgeschalteten Multiplikation ein Zahlenüberlauf stattfinden, bei der nachgeschalteten Multiplikation aber nur dann, wenn das Gesamtergebnis > High(Int64) wird. Somit dürfte diese Konstruktion zuverlässiger arbeiten. |
Re: Zahl als Bruch speichern
mh... im Grunde habt ihr recht. Beachtet aber bitte, das c hier der ggt von a und b ist:
/ entspicht div a = 6 b = 4 c = ggt(6,4) = 2 (a x b) / c = (6 x 4) / 2 = 24 / 2 = 12 a x (b / c) = 6 x (4 / 2) = 6 x 2 = 12 b x (a / c) = 4 x (6 / 2) = 4 x 3 = 12 in diesem speziellen Fall entspricht (a x b) / c auch a x (b / c) und b x (a / c) Edit: Das kommt davon, wenn man früh morgens nur den halben letzten Beitrag liest... :duck: Edit2: Bei negativen Bruchzahlen kommts unweigerlich zum Crash. GGT darf nur Absolutwerte annehmen! |
Re: Zahl als Bruch speichern
Zitat:
Ich sehe im Moment keinen Grund, warum die von ws1976 vorgestellte GGT-Version Probleme mit negativen Zahlen haben sollte. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:49 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz