isNumber Function wird nicht gefunden

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Benutzeravatar
Levario
Beiträge: 101
Registriert: Mo 1. Sep 2014, 14:32
OS, Lazarus, FPC: Windows 10 Pro Laptop (Lazarus 3.0.0 FPC 3.2.2)
CPU-Target: 64 Bit
Wohnort: Deutschland / NRW

isNumber Function wird nicht gefunden

Beitrag von Levario »

Hallo zusammen

ich möchte prüfen ob ein String eine Zahl ist und habe die Funktion isNumber gefunden.
Die Funktion wird bei mir nicht gefunden. Was muss ich bei uses für eine classe angeben damit ich diese verwenden kann?

Wie kann ich das aus der Freepascal.org seite herauslesen?
https://www.freepascal.org/docs-html/rt ... umber.html

Danke für eure Hilfe
Gruß
Levario
Der Weg ist das Ziel... Aber bitte nicht vergessen los zu laufen :).

Linkat
Lazarusforum e. V.
Beiträge: 530
Registriert: So 10. Sep 2006, 23:24
OS, Lazarus, FPC: Linux Mint 21.3; Lazarus 3.0 FPC 3.2.2; RaspiOS
CPU-Target: AMD 64, ARM 32
Wohnort: nr Stuttgart

Re: isNumber Function wird nicht gefunden

Beitrag von Linkat »

Hallo Levario,
die Unit die du suchst heist

Code: Alles auswählen

character
und steht auf der Seite

https://www.freepascal.org/docs-html/rt ... umber.html

ganz oben rechts.

Aber die Funktion gilt für Unicode.

Viel Erfolg.
Linux Mint 21; Lazarus 2.2.4 FPC 3.2.2; RaspiOS

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: isNumber Function wird nicht gefunden

Beitrag von wp_xyz »

Es kommt drauf an, was du unter "Zahl" verstehst. Integer oder Gleichkomma? In jedem Fall kannst bei einer versuchsweise Umwandung in einen String feststellen, ob es sich um eine gültige Zahl handelt: TryStrToInt bzw. TryStrToFloat. Beide Funktionen geben einen boolschen Wert zurück, wenn es sich um einen gültigen Integer bzw. Float handelt. Im Gegensatz zu StrToInt bzw. StrToFloat wird keine Exception ausgelöst.

Code: Alles auswählen

funtion IsInteger(s: String): boolean;
var
  n: Integer;
begin
  Result := TryStrToInt(s, n);
end;

function IsFloat(s: String): Boolean;
var
  x: Double;
begin
  Result := TryStrToFloat(s, x);
end;

wennerer
Beiträge: 507
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 20 Cinnamon,Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-
CPU-Target: x86_64-linux-gtk2

Re: isNumber Function wird nicht gefunden

Beitrag von wennerer »

Hallo Levario,
falls du mal wieder auf der Suche nach der richtigen Unit bist kannst du auch folgendes machen:
Verwende einfach den gewünschten Befehl und erzeuge eine Fehlermeldung.
cody1.png
cody1.png (30.29 KiB) 2650 mal betrachtet
Klicke dann mit der rechten Maustaste auf die Fehlermeldung. Es öffnet sich dieses Fenster:
cody2.png
cody2.png (26.69 KiB) 2650 mal betrachtet
Hier dann auf Zeige Cody-Verzeichnis für ... klicken. Es öffnet sich folgendes Fenster:
cody3.png
cody3.png (32.59 KiB) 2650 mal betrachtet
In dem Fall hast du zwei Möglichkeiten zur Wahl: LazStringUtils oder Character.Jetzt auf Verwende Bezeichner. Nun wird die gewählte Unit eingefügt.
Hat mir schon oft weitergeholfen, vielleicht hilft es dir ja auch irgendwann mal weiter.

Viele Grüße
Bernd

Soner
Beiträge: 623
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: isNumber Function wird nicht gefunden

Beitrag von Soner »

Wenn es um die Prüfung ob ein String eine Zahl enhält geht, dann verwende einfach die gute alte Pascal-Funktion Val.
Alle anderen Funktionen wie StrToInt, TryStrToInt u.s.w. benutzen intern Val.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: isNumber Function wird nicht gefunden

Beitrag von Winni »

Hi!

Ich hänge mich dann an Soners Idee mit val dran:

Code: Alles auswählen

function isThisANumber(s : string) : string;
var err0,err1 : integer;
    i: integer;
    f: single;
begin
 Val(s,i,err0);
 if err0 = 0 then result := 'integer' else
   begin
   val (s,f,err1);
   if err1 = 0 then result := 'float' else
      result := 'no';
     end;
end;
Und zum Testen gleich mal diese Funktion:

Code: Alles auswählen

procedure TForm1.Button4Click(Sender: TObject);
const TestNum : array[0..2] of string= ('0815','3.14159','Lazarus');
var s : string;
    i : integer;

begin
   for i := 0 to 2 do
     begin
      s := isThisANumber(TestNum[i]);
      showMessage (TestNum[i]+LineEnding+s);
       end;
end;
Gruß
Winni

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: isNumber Function wird nicht gefunden

Beitrag von m.fuchs »

Soner hat geschrieben:
Fr 3. Sep 2021, 20:24
Alle anderen Funktionen wie StrToInt, TryStrToInt u.s.w. benutzen intern Val.
IsNumber benutzt Val nicht. Und beide arbeiten auch unterschiedlich. Während Val auch Hexadezimal-, Binär- oder Oktal-Darstellung verarbeiten kann, prüft IsNumber ob der String ausschließlich die Ziffern 0 bis 9 enthält. Je nach Anforderung kann man eines nicht mit dem anderen ersetzen.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: isNumber Function wird nicht gefunden

Beitrag von Winni »

m.fuchs hat geschrieben:
Fr 3. Sep 2021, 20:43

IsNumber benutzt Val nicht. Und beide arbeiten auch unterschiedlich. Während Val auch Hexadezimal-, Binär- oder Oktal-Darstellung verarbeiten kann, prüft IsNumber ob der String ausschließlich die Ziffern 0 bis 9 enthält. Je nach Anforderung kann man eines nicht mit dem anderen ersetzen.
Natürlich kann man das.
Müss man nur überprüfen, ob val zur Wandelung auf ein Qword einen Error auswirft.
Dann macht es genau das Gleiche wie IsNumber.

Winni

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: isNumber Function wird nicht gefunden

Beitrag von m.fuchs »

Winni hat geschrieben:
Fr 3. Sep 2021, 20:50
Müss man nur überprüfen, ob val zur Wandelung auf ein Qword einen Error auswirft.
Dann macht es genau das Gleiche wie IsNumber.
Irgendwie verstehe ich nicht was du meinst.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: isNumber Function wird nicht gefunden

Beitrag von Winni »

Code: Alles auswählen

Function isNumber(s: string) : boolean;
var q: Qword;
       err : integer;
begin
val (s,q,err);
result := err=0;
end

Benutzeravatar
Levario
Beiträge: 101
Registriert: Mo 1. Sep 2014, 14:32
OS, Lazarus, FPC: Windows 10 Pro Laptop (Lazarus 3.0.0 FPC 3.2.2)
CPU-Target: 64 Bit
Wohnort: Deutschland / NRW

Re: isNumber Function wird nicht gefunden

Beitrag von Levario »

Vielen lieben Dank! Für die vielen Antworten werde es morgen mal testen.
Der Weg ist das Ziel... Aber bitte nicht vergessen los zu laufen :).

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: isNumber Function wird nicht gefunden

Beitrag von m.fuchs »

@Winnie: Der Code verhält sich immer noch nicht wie die originale IsNumber.

Code: Alles auswählen

function isNumberWinni(s: string) : boolean;
var q: Qword;
       err : integer;
begin
val (s,q,err);
result := err=0;
end;

begin
  WriteLn(IsNumber('0xFFFF'));
  WriteLn(isNumberWinni('0xFFFF'));
end.
Ausgabe:

Code: Alles auswählen

FALSE
TRUE
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: isNumber Function wird nicht gefunden

Beitrag von Winni »

Ja, meistens sitzt das Problem vor dm Bildschirm ...

BeniBela
Beiträge: 308
Registriert: Sa 21. Mär 2009, 17:31
OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
CPU-Target: 64 Bit

Re: isNumber Function wird nicht gefunden

Beitrag von BeniBela »

Letztens habe ich einen TryStrToInt Ersatz programmiert: https://forum.lazarus.freepascal.org/in ... #msg414973

Den kann man hierfür anpassen, wenn man die Berechnung des unsigned Ergebnis und die Längenbegrenzung entfernt.

Für acht stellig Zahlen dürfte das 50% schneller sein als IsNumber

Soner
Beiträge: 623
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: isNumber Function wird nicht gefunden

Beitrag von Soner »

BeniBela hat geschrieben:
Fr 3. Sep 2021, 23:30
Letztens habe ich einen TryStrToInt Ersatz programmiert: https://forum.lazarus.freepascal.org/in ... #msg414973

Den kann man hierfür anpassen, wenn man die Berechnung des unsigned Ergebnis und die Längenbegrenzung entfernt.

Für acht stellig Zahlen dürfte das 50% schneller sein als IsNumber
Deine Zeitangaben im englischen Forum waren für mich beindruckend, deshalb habe ich es gestestet. Val ist nicht so sehr viel langsamer als deine Funktion, und Val hat auch Längenkontrolle und kann mit mehreren Zahlenformate umgehen.
Deine Funktion war für die Zahl 9223372036854775808 nach 10.000.000 durchläufen etwa 470 ms schnell und val 710ms.
Ich habe dann Funktion erweitert mit negativen Zahlen und das Weglassen von Längenübergabe beim Funktionsaufruf, dann wurde deine Funktion etwa 520ms schnell.
Trotzdem finde ich deine Funktion gut, weil man eine Konvertierungsfunktion basteln kann, dass auch mit Tausenderzeichen umgehen kann.

Ich habe aus deiner Funktion IstStrEineZahl-Funktion gebastelt, dass auch lokale Tausendertrennzeichen, Dezimalzeichen und mit Plus- und Minuszeichen umgehen kann. wobei String und somit auch die Zahl unendlich lang sein können.

Code: Alles auswählen

//Benibelas-funktion für negative Zahlen erweitert
function simplestTryPcharToInt(pstart, pend: pchar; out unsigned: Int64): boolean;
var
  length: SizeUInt;
  pstart0: pchar;
  signed: boolean;//son
begin
  result := false;
  if pend <= pstart then exit;
  while (pstart < pend) and (pstart^ = '0') do inc(pstart);
  length := pend - pstart;
  if length > 20 then exit;
  if (length = 20) and (pstart^ >= '2') then exit;
  unsigned := 0;
  pstart0:=pstart; //son
  signed:=false;        //son
  while (pstart < pend) do begin
    case pstart^ of
    '0'..'9': unsigned := unsigned * 10 + (ord(pstart^) - ord('0'));
    '-': if pstart<>pstart0 then exit            //son
          else if not signed then signed:=true; //son
    else exit;
    end;
    inc(pstart);
  end;
  if (length = 20) and (unsigned < 10000000000000000000) then exit;
  result := true;
  if signed then unsigned:=unsigned*-1;
end;

//Benibelas-funktion für negative Zahlen erweitert und längenüberage beim Funktionsaufruf entfernt
function simplestTryPcharToIntRealistisch(pstart: pchar; out unsigned: Int64): boolean;
var
  pstart0: pchar;
  signed: boolean;//son
begin
  result := false;
//  if pend <= pstart then exit;
//  while (pstart < pend) and (pstart^ = '0') do inc(pstart);
//  length := pend - pstart;
//  if length > 20 then exit;
//  if (length = 20) and (pstart^ >= '2') then exit;
  unsigned := 0;
  pstart0:=pstart; //son
  signed:=false;        //son
  while (pstart^ <> #0) do begin
    case pstart^ of
    '0'..'9': unsigned := unsigned * 10 + (ord(pstart^) - ord('0'));
    '-': if pstart<>pstart0 then exit            //son
          else if not signed then signed:=true; //son
    else exit;
    end;
    inc(pstart);
  end;
  //if (length = 20) and (unsigned < 10000000000000000000) then exit;
  if pstart=pstart0 then Result:=false //stringlänge=0
  else result := true;
  if signed then unsigned:=unsigned*-1;
end;

function IstStrEineZahl(pstart: pchar): boolean;
var pstart0: pchar;
    decsep: integer;
begin
  result := false;
  pstart0:=pstart; //son
  decsep:=0;
  while (pstart^ <> #0) do begin
    case pstart^ of
    '0'..'9': ; //nichts tun
    '-','+': if pstart<>pstart0 then exit;
    else begin
        if pstart^=DecimalSeparator then begin
           Inc(decsep);
           if decsep>1 then exit;
        end
        else if pstart^<>ThousandSeparator then exit;
      end;
    end;
    inc(pstart);
  end;
  result := true;
end;

procedure TForm1.FormCreate(Sender: TObject);
var t1,t2: QWord;
    s: AnsiString;
    r, i, c: integer;
    o: int64;

begin
  s:='-9223372036854775808';
  t1:=GetTickCount64;
  for c:=1 to 10000000 do
    Val(s,i,r);
  t2:=GetTickCount64;
  Memo1.Lines.Add('Val: '+r.ToString+' in ms:'+IntToStr(t2-t1));

  t1:=GetTickCount64;
  for c:=1 to 10000000 do
    simplestTryPcharToIntRealistisch(pchar(s),o);
  t2:=GetTickCount64;
  Memo1.Lines.Add('s: '+o.ToString()+'  ms: '+IntToStr(t2-t1));


  t1:=GetTickCount64;
  for c:=1 to 10000000 do
    IstStrEineZahl(pchar(s));
  t2:=GetTickCount64;
  Memo1.Lines.Add('Zahl?: '+IntToStr(t2-t1));

  //test 2
  t1:=GetTickCount64;
  for c:=1 to 10000000 do
    IstStrEineZahl(pchar('-9.720.368.547.758,08'));
  t2:=GetTickCount64;
  Memo1.Lines.Add('Zahl? 2.: '+IntToStr(t2-t1));
end;

Antworten