![]() |
Zahl als Bruch speichern
Hi DP
ich hätte da mal ne Frage und hoffe ihr könnt mir dabei helfen es geht nämlich um folgendes: ich hab ne real variable und wenn ich z.B. 2 durch 3 teile dann muss der ja irgendwann runden... nun hab ich ein Programm in dem es erforderlich ist, dass er eben nciht rundet... unendlich viele nachkommastellen kann ich gleich vergessen, schon klar! was cih bräuchte wäre dann wohl statt real etwas, was statt zu runden bruchwerte annimmt... kennt ihr da sowas? (oder ahbt ihr ne Idee wie ichs lösen könnte?) danke im vorraus! lg Dino |
Re: genauen wert
Bei "2 geteilt durch 3" wirst du vermutlich kein Rundungsproblem bekommen.
Bei "1245 durch 524" schon eher. Versuch doch mal den grössten Float-Datentyp für die Rechnung zu verwenden. Anschliessend castest Du auf einen kleineren Float-Datentyp. Dann könnte sein, dass nur "abgeschnitten" wird. |
Re: genauen wert
2 durch 3 war vorher 0.66[..]667 so wie du es sagst wäre es ja dann 0.66[..]66 ...
das stimmt aber ja dann ebenfalls nciht... also nur abgeschnitten ist mir für den zweck schon zu viel, sorry der müsste schon dann halt den wert 2/3 annehmen |
Re: genauen wert
Dann musst du dir die Zahlen eben als Bruch merken (oder als Wurzel, wenn du alle reelen Zahlen haben willst).
|
Re: genauen wert
Schreibe dir doch eine Klasse die mich Brüchen arbeiten kann oder suche dir eine schon fertige aus (ich weiß gerade nicht ob es in der DP schon fertige Klassen dafür gibt).
Flare |
Re: genauen wert
es sind wirklich nur brüche und keine wurzeln...
wie das mt der klasse geht weiss ich ncoh net so ganz :( klassen wären z.B. real, extended, single, integer u.s.w., oder? also was in meinem programm (extrem vereinfacht) passiert ist folgendes:
Delphi-Quellcode:
var
xr,yr,fr:real; i,fori:Integer; for fori := 0 to 1000 do begin fr:=-xr/i; xr:=xr+(i*fr); yr:=yr+(i*fr); // und hier zwischen passiert halt auch ncoh einges, was aber mit dem Problem wenig zu zun hat end; |
Re: genauen wert
also ich denke ich brauche für diesen zweck einfach ne eigene klasse
wo finde ich informationen dazu wie ich mir eine mache oder ob es schon eine richtige für mcih gibt? ![]() |
Re: genauen wert
Du brauchst eigentlich nur soetwas:
Delphi-Quellcode:
Die Prozeduren zu den Grundrechenarten musst du natürlich noch implementieren. Das dürfte aber wohl nicht allzu kompliziert sein und sich mit Mathe aus der sechsten Klasse lösen lassen. :zwinker:
type
TBruch = class(TObject); public zaehler, nenner: integer; // Oder Int64 bei sehr großen Zahlen procedure add(bruch: TBruch); procedure sub(bruch: TBruch); procedure mul(bruch: TBruch); procedure divide(bruch: TBruch); // div geht nicht, weil das ja ein geschützter begriff ist... end; |
Re: genauen wert
Man sollte natürlich noch eine Methode "kürzen" implementieren, dass man nicht so schnell an die Grenzen von integer kommt :zwinker:
|
Re: genauen wert
@sirius slbstverständlich
nun sagt er aber "= erwartet aber zaehler gefudnen :(" |
Re: genauen wert
Das Semikolon hinter class(TObject) ist zuviel :zwinker:
|
Re: genauen wert
ah danke (weiss zwar net warum, aber ich hoffe mal ihr sagts mir ;))
nun scheitert er bei x:=0; (var x:TBruch) wie mach ich das nun? also dass er per :=integer nenner auf 1 setzt und den integerwert dann an den zähler übergibt? edit: ich vermute mal, dass ich hierfür zwingend nen inttobruch brauche und probiere es mal aus) |
Re: genauen wert
Na du kannst jetzt nicht mehr mit "normaler" Zuweisung etc arbeiten, sondern nur mit Methoden oder Properties.
|
Re: genauen wert
habs nun so gelöst
Delphi-Quellcode:
1.war es das was du meintest?
var
Form1: TForm1; implementation {$R *.DFM} function inttobruch(i:Integer):Tbruch; begin result.zaehler:=i; result.nenner:=1; end; 2.so richtig? 3. an der richtigen stelle? |
Re: genauen wert
Also, am besten du schaust dir mal
![]() |
Re: genauen wert
Zitat:
Dafür musst du dir jedenfalls keine Klasse schreiben... Mit einem sinnigeren Beispiel in der Hand könnte man vielleicht noch einen anderen Weg vorschlagen, aber so wird's schwer. |
Re: genauen wert
danke, ich werds mir anschauen
und @Khabarakh: ja es hat Sinn!!! und wenn ich mir keine Klasse schreiben muss, was dann? und was ist für dich ein sinniges beispiel??? |
Re: genauen wert
Zitat:
|
Re: genauen wert
Zitat:
ja genau genommen siehts ja auch so aus:
Delphi-Quellcode:
var
xr,yr,fr,fr1,fr2:real; i1,i2,fori:Integer; for fori := 0 to 1000 do begin fr1:=-xr/i1; fr2:=-yr/i2; fr:=fr1; if fr2<fr then fr:=fr2; xr:=xr+(i1*fr); //klar, hier wirds net gebraucht yr:=yr+(i2*fr); // und hier zwischen passiert halt auch ncoh einges, was aber mit dem Problem wenig zu zun hat end; |
Re: genauen wert
Zitat:
Zitat:
|
Re: genauen wert
was sit denn eine assign methode?
steht wohl in dem "Buch" drin, was cih eben gekreigt habe (was ich gerade am durchlesen bin) |
Re: Zahl als Bruch speichern
Mit Assign kopiert man Daten von einem Object in ein anderes des gleichen Typs
Delphi-Quellcode:
var Bruch1, Bruch2:TBruch
begin ... Bruch2.Assign(Bruch1); // In Bruch 2 steht nun das, was in Bruch1 steht ... end; |
Re: Zahl als Bruch speichern
und wie und wofür brauche ich das jetzt genau? :gruebel:
|
Re: Zahl als Bruch speichern
Da Du nicht Bruch2:=Bruch1; machen kannst.
|
Re: Zahl als Bruch speichern
Zitat:
|
Re: Zahl als Bruch speichern
Es empfiehlt sich aber die Namen bei zu behalten.
|
Re: Zahl als Bruch speichern
meint ihr ne property?
edit: wobei ne property ja nur für zähler und nenner einzeln gemacht wird wie macht man ne property für die ganze klasse sodass ich dann den bruch := irgendwas setzen kann, oder etwas := bruch machen kann |
Re: Zahl als Bruch speichern
Du merkst gerade selbst, dass ein Bruch als Referenztyp (Klasse) nicht viel Sinn macht, ein Wertetyp (Record) wäre viel sinnvoller - denn den kannst du dann wirklich per var2 := var 1 kopieren. Mit Delphi 5 kannst du dann nur prozedural weiterarbeiten (soll heißen, du schreibst globale Funktionen wie AddiereBrueche(Bruch1, Bruch2: TBRuch): TBruch), was aber bei deinem OOP-Kenntnisstand vielleicht gar nicht so unsinnvoll ist.
|
Re: Zahl als Bruch speichern
kompromiss: ich werde wieter OOP lernen und ihr sagt mir dafür wie ich das mit diesem wertetyp Record mache, ok? :)
|
Re: Zahl als Bruch speichern
Delphi-Quellcode:
type
Txyz=packed record x:Integer; y:Integer; z:Integer; end; var xyz:Txyz; begin xyz.x:=1; xyz.y:=2: ... |
Re: Zahl als Bruch speichern
was heisst packed record und was gibts da für alternativen?
also das sieht so wie es aussieht schon vernünftiger für mcih aus nur wäre es auch schön, wenn ich dabei auch noch xyz1+xyz2 ermöglichen könnte also dass ich dann ergendwie festlege, dass wenn man ihn mit nem typ Txyz multipliziert, dass dann x,y und z jeweils addiert werden solen, oder dass wenn man dazu nen integer addiert, dass der integerwert einfach zu x addiert werden soll oder wenn man zu nem integer das addiert, dann soll zum integer x,y und z addiert werden sowas halt... |
Re: Zahl als Bruch speichern
Das geht nur mit neueren Versionen, mit Delphi 5 wird's dann eben irgendwie so aussehen:
Delphi-Quellcode:
Ist aber noch erträglich, oder :zwinker: ?
Summe := AddiereBrueche(Buch1, Bruch2);
|
Re: Zahl als Bruch speichern
ist das jetzt für den fall klasse oder für den fall type record?
|
Re: Zahl als Bruch speichern
Das is was für ein Record
|
Re: Zahl als Bruch speichern
achso
ja schade aber es ist wirklcih erträglcih (musste heute schon härtere schicksalsschläge hinnehmen) |
Re: Zahl als Bruch speichern
Liste der Anhänge anzeigen (Anzahl: 1)
wollte nur bescheid sagen, dass ich es jetzt mit record geschafft habe
hab mir ne eigene unit dafür gemacht wer also mal mit brüchen arbeiten möchte, der kann sich ja meine anschauen und ggf anpassen edit: also zähler hab cih eunfach mal a und nenner b genannt... mal, geteilt, plus, minus mit brüchen oder integer alles mit drin dazu noch ein kleines bisschen kürzen(für miene zwecke ausreichend) bruchtostr und noch einiges mehr ist auch noch drin edit2: was ich eigetnlich sagen wollte: Danke für eure Hilfe! durch euch hab ich nun auch das geschafft |
Re: Zahl als Bruch speichern
falls ich rückmeldung zu der unit wünsche muss ichs wohl als eigenes Thema veröffentlichen, oder?
|
Re: Zahl als Bruch speichern
Schau mal da:
![]() |
Re: Zahl als Bruch speichern
Hallo,
hier meine Lösung:
Delphi-Quellcode:
Grüsse
unit U_bruchrechnen;
interface Type Bruchtyp=packed record z,n: int64; // Int64 wegen sehr großer Zahlen end; TBruch = class(TObject) //kleinsten gemeinsamen Teiler ermitteln function ggt(b0,b1:int64):int64; //kleinstes gemeinsames Vielfaches ermitteln function kgv(b0,b1:int64):int64; //Bruch kürzen function red(b0,b1:int64):Bruchtyp; //Bruch bo und b1 addieren function add(b0,b1: Bruchtyp):Bruchtyp; //Von Bruch b0 Bruch b1 abziehen function sub(b0,b1: Bruchtyp):Bruchtyp; //Bruch bo und b1 multiplizieren function mul(b0,b1: Bruchtyp):Bruchtyp; //Bruch bo durch Bruch b1 dividieren function divide(b0,b1: Bruchtyp):Bruchtyp; end; implementation 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.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.kgv(b0,b1:int64):int64; Begin result:=b0*b1 div ggt(b0,b1); 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: Bis auf die Grundrechenarten ist alles aus der DP zusammengesucht. |
Re: Zahl als Bruch speichern
Die Methoden red, ggt und kgv sollten als private deklariert werden, weil man die nie braucht und sie daher eh nur innerhalb der Klasse verwendet werden.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:29 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