Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Zahl als Bruch speichern (https://www.delphipraxis.net/100045-zahl-als-bruch-speichern.html)

dino 21. Sep 2007 13:15


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

RavenIV 21. Sep 2007 13:39

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.

dino 21. Sep 2007 13:43

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

sirius 21. Sep 2007 13:47

Re: genauen wert
 
Dann musst du dir die Zahlen eben als Bruch merken (oder als Wurzel, wenn du alle reelen Zahlen haben willst).

Flare 21. Sep 2007 13:47

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

dino 21. Sep 2007 14:17

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;

dino 21. Sep 2007 14:35

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?

DP-Suche schon klar, aber wenn ich z.B. "eigene klasse schreiben" eingebe suche ich mich duselig...

Namenloser 21. Sep 2007 14:51

Re: genauen wert
 
Du brauchst eigentlich nur soetwas:
Delphi-Quellcode:
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;
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:

sirius 21. Sep 2007 15:03

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:

dino 21. Sep 2007 15:08

Re: genauen wert
 
@sirius slbstverständlich

nun sagt er aber "= erwartet aber zaehler gefudnen :("

sirius 21. Sep 2007 15:09

Re: genauen wert
 
Das Semikolon hinter class(TObject) ist zuviel :zwinker:

dino 21. Sep 2007 15:12

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)

sirius 21. Sep 2007 15:19

Re: genauen wert
 
Na du kannst jetzt nicht mehr mit "normaler" Zuweisung etc arbeiten, sondern nur mit Methoden oder Properties.

dino 21. Sep 2007 15:24

Re: genauen wert
 
habs nun so gelöst

Delphi-Quellcode:
var
  Form1: TForm1;

implementation

{$R *.DFM}

function inttobruch(i:Integer):Tbruch;
begin
  result.zaehler:=i;
  result.nenner:=1;
end;
1.war es das was du meintest?
2.so richtig?
3. an der richtigen stelle?

g0rmed 21. Sep 2007 15:31

Re: genauen wert
 
Also, am besten du schaust dir mal das (ab S.48 ) an. Es kann ja nicht sein, dass du nicht weißt was du falsch machst :) .

Khabarakh 21. Sep 2007 15:36

Re: genauen wert
 
Zitat:

Zitat von dino
Delphi-Quellcode:
fr:=-xr/i;
xr:=xr+(i*fr);
yr:=yr+(i*fr);

Sinn :gruebel: ?
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.

dino 21. Sep 2007 15:43

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???

Khabarakh 21. Sep 2007 15:49

Re: genauen wert
 
Zitat:

Zitat von dino
und was ist für dich ein sinniges beispiel???

Jedenfalls keines, das durch eine Zahl teilt und sofort wieder mit dieser multipliziert, sodass ganzzahlige Arithmetik vollkommen ausreichend wäre.

dino 21. Sep 2007 15:59

Re: genauen wert
 
Zitat:

Zitat von g0rmed
Also, am besten du schaust dir mal das (ab S.48 ) an. Es kann ja nicht sein, dass du nicht weißt was du falsch machst :) .

meinteste etwa, dass ich meine Klasse Bruch wenn cih sie schon erstelle auch als eigene unit machen sollte?

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;

sirius 21. Sep 2007 16:04

Re: genauen wert
 
Zitat:

ja genau genommen siehts ja auch so aus:
Wenn nicht mehr kommt, ist eine Klasse natürlich etwas Overkill. Aber wenn du in deinem Projekt ständig mit genauen rationalen Zahlen rechnen willst, ist eine Klasse die bessere Lösung.

Zitat:

meinteste etwa, dass ich meine Klasse Bruch wenn cih sie schon erstelle auch als eigene unit machen sollte?
Nein, er meinte du sollst eine Art Assign Methode in die Klasse bauen, sodass du dann z.B. myBruch.assign(Zähler,Nenner) aufrufen kannst. Bzw. du sollst objektorientier programmieren und jede einfache Funktion läuft natürlich gegen OOP. (Aber deswegen nicht generell OOP als das NonPlusUltra ansehen!)

dino 21. Sep 2007 16:17

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)

Sunlight7 21. Sep 2007 16:35

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;

dino 21. Sep 2007 16:41

Re: Zahl als Bruch speichern
 
und wie und wofür brauche ich das jetzt genau? :gruebel:

Sunlight7 21. Sep 2007 16:44

Re: Zahl als Bruch speichern
 
Da Du nicht Bruch2:=Bruch1; machen kannst.

sirius 21. Sep 2007 16:45

Re: Zahl als Bruch speichern
 
Zitat:

Zitat von dino
und wie und wofür brauche ich das jetzt genau? :gruebel:

Wie gesagt: Ob du das brauhst, wissen wir ja nicht, da wir dein Projekt nicht kennen. Wenn du aber auf einen Vorschlag (den mit der Klasse bauen) eingehst, dann brauchst du eben für die Klasse verschiedene Methoden. Die darfst du dir selber ausdenken, da bist du ganz frei. die Methode zum Zuweisen von Werten (für gesamten Inhalt einer Klasse) nennt man meistens "assign". Kann aber auch ganz anders heissen.

Sunlight7 21. Sep 2007 17:16

Re: Zahl als Bruch speichern
 
Es empfiehlt sich aber die Namen bei zu behalten.

dino 21. Sep 2007 19:04

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

Khabarakh 21. Sep 2007 19:32

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.

dino 21. Sep 2007 19:39

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? :)

Sunlight7 21. Sep 2007 19:44

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:
...

dino 21. Sep 2007 19:48

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...

Khabarakh 21. Sep 2007 20:01

Re: Zahl als Bruch speichern
 
Das geht nur mit neueren Versionen, mit Delphi 5 wird's dann eben irgendwie so aussehen:
Delphi-Quellcode:
Summe := AddiereBrueche(Buch1, Bruch2);
Ist aber noch erträglich, oder :zwinker: ?

dino 21. Sep 2007 21:11

Re: Zahl als Bruch speichern
 
ist das jetzt für den fall klasse oder für den fall type record?

Sunlight7 21. Sep 2007 21:42

Re: Zahl als Bruch speichern
 
Das is was für ein Record

dino 21. Sep 2007 21:53

Re: Zahl als Bruch speichern
 
achso

ja schade aber es ist wirklcih erträglcih (musste heute schon härtere schicksalsschläge hinnehmen)

dino 23. Sep 2007 10:13

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

dino 14. Okt 2007 20:43

Re: Zahl als Bruch speichern
 
falls ich rückmeldung zu der unit wünsche muss ichs wohl als eigenes Thema veröffentlichen, oder?

Sunlight7 14. Okt 2007 22:00

Re: Zahl als Bruch speichern
 
Schau mal da: Open Source ;)

WS1976 15. Okt 2007 05:55

Re: Zahl als Bruch speichern
 
Hallo,

hier meine Lösung:

Delphi-Quellcode:
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.
Grüsse
Rainer

PS: Bis auf die Grundrechenarten ist alles aus der DP zusammengesucht.

alzaimar 15. Okt 2007 07:09

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 09:39 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz