Entwickler-Ecke

Algorithmen, Optimierung und Assembler - Funktion IstGanzeZahl: Ist ein Realwert ganzzahlig?


Jakob Schöttl - Mo 05.03.07 17:21
Titel: Funktion IstGanzeZahl: Ist ein Realwert ganzzahlig?
Hallo,

Ich bräuchte eine Funktion, die mir angibt, ob ein Real- bzw. Extended-Ausdruck eine ganze Zahl ist. Leider hab ich keine Funktion gefunden bei Delphi. Kann man sowas vllt mit
if Frac(x{real}) = 0.0000000000000 then Result := True; realisieren?

Oder gibt es da doch schon was fertiges?

Danke schon mal!


Calculon - Mo 05.03.07 17:28

Naja, du könntest z.B. folgenden Umweg gehen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
{ var
  str: string;
  int: integer;
  x: extended; }


str := floattostr(x);
try
  int := strtoint(str);
  result := true;
except
  result := false;
end;

oder so ähnlich.

Gruß

Calculon
--


Kroko - Mo 05.03.07 17:29

Wie wäre es mit FRAC


Jakob Schöttl - Mo 05.03.07 17:34
Titel: Re: Funktion IstGanzeZahl: Ist ein Realwert ganzzahlig?
user profile iconJakob Schöttl hat folgendes geschrieben:

Delphi-Quelltext
1:
if Trunc(x{real}) = 0.0000000000000 then Result := True;                    

hier meinte ich natürlich Frac ;)

Nun ja, so wie user profile iconCalculon es gemacht hat, so mache ich es dann wahrscheinlich auch. Auch wenn es nicht so schön ist, aber ich glaub fast, was besseres gibt es nicht...


Calculon - Mo 05.03.07 17:57

Hi nochmal,

hab' grad was ausprobiert und scheint auch zu klappen. Vielleicht gefällt dir das ja besser:


Delphi-Quelltext
1:
2:
if round(strtofloat(edit1.text)) <> strtofloat(edit1.Text) then showmessage('FLOATING VALUE')
else ShowMessage('INTEGER VALUE');

Gruß

Calculon
--


IngoD7 - Mo 05.03.07 17:58

:?: Öööhm ... ich kann euch inhaltlich - glaube ich - nicht ganz folgen.

Aber folgendes funktioniert doch:


Delphi-Quelltext
1:
2:
if Frac(x) = 0 then 
   IchBinGanz := true;


//Nachtrag:
Es funktioniert mit der diesen Funktionen zugrunde liegenden Ungenauigkeiten. :(
5,0000000000000001 würde er als Ganzzahl erkennen.

//Nachtrag 2:
Und eigentlich wollte ich mich ja gar nicht selbst quoten, sondern mein Vorposting nur editieren. :cry:
Ich muss langsam Feierabend machen .....

Moderiert von user profile iconjasocul: Beiträge zusammengefasst


Jakob Schöttl - Mo 05.03.07 18:31

user profile iconIngoD7 hat folgendes geschrieben:

Delphi-Quelltext
1:
2:
if Frac(x) = 0 then 
   IchBinGanz := true;

... mit Ungenauigkeiten ...


Aber ich glaube ich nehme dann doch diese Funktion, weil solche Ungenauigkeiten treten wahrscheinlich bei FloatToStr auch auf.

Dann siehts also so aus:

Delphi-Quelltext
1:
2:
3:
4:
function IstGanzeZahl(x: extended): Boolean;
begin
  if Frac(x) = 0 then result := True else Result := False; { Das ist übrigens hundertmal schenller als mit dem try ... except und FloatToStr... }
end;


Gut, Danke mal wieder an alle!


Kroko - Mo 05.03.07 19:47

So wäre es kürzer

Delphi-Quelltext
1:
2:
3:
4:
function IstGanzeZahl(x: extended): Boolean;
begin
  Result := Frac(x) = 0;
end;

und so wäre es genauer

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
function IstGanzeZahl(x: extended): Boolean;
const 
  Epsilon = 1E-10// anpassen
begin
  Result := ABS(Frac(x)(<Epsilon;
end;

//EDIT: ABS hinzugefügt


Allesquarks - Mo 05.03.07 20:02

Ich muss jetzt weg kann die genauen Befehle also gerade nicht raussuchen.

Aber In FPU runden FPRDINT irgendwieso und dann vergleichen und Flags setzen oder halt eax als resultat einer Funktion
FCOMIP dürte da sehr hilfreich sein.


BenBE - Mi 07.03.07 03:30

@Kroko: Fast richtig ...


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
function IstGanzeZahl(x: extended): Boolean;
const 
  Epsilon = 1E-10// anpassen
begin
  Result := Abs(Frac(x))<Epsilon;
end;


Ansonsten meint er -5.25 ist eine Ganzzahl :P


Kroko - Mi 07.03.07 06:30

//EDIT: Abs gehört mit rein, reisen Denkfehler :oops: