![]() |
UInt64 Typ-Problem bei Vorgabewerten
Hallo
Ich habe mir da eine Funktion gebastelt für UInt64 ...
Delphi-Quellcode:
Wenn man diese Funktion verwendet mit den vorgespannten Vorgabewerten ...
function StrToU64(const S:string; Default:UInt64=0; aMin:UInt64=Low(UInt64); aMax:UInt64=High(UInt64)): UInt64;
var E: Integer; begin Val(S, Result, E); if E=1 then result:=Default; result:=Min(aMax, Max(aMin, result)); end; MyU64:=StrToU64('123'); ... dann bekomme ich in Delphi2007 folgenden Compilerfehler:
Delphi-Quellcode:
Wenn man aber alle Werte mit übergibt, dann scheint es zu gehen ...
[DCC Fehler]: E1012 Konstantenausdruck verletzt untere Grenzen
MyU64:=StrToU64('123', 0, Low(UInt64), High(Uint64)); Was läuft hier schief?!? Im übrigen: Wenn man Int64 nimmt, dann geht alles super. Gruß Ma2xx |
Re: UInt64 Typ-Problem bei Vorgabewerten
Welche Delphi-Version?
AFAIK existieren in älteren Version noch Probleme mit (U)Int64 an diversen Stellen. |
Re: UInt64 Typ-Problem bei Vorgabewerten
Das ist ein Fehler bei der Umsetzung des vorzeichenlosen Typs Int64. Das geht nur zur Laufzeit. Deshalb musst du hier überladene Methoden benutzen.
|
Re: UInt64 Typ-Problem bei Vorgabewerten
Zitat:
und das nicht nur im Compiler, sondern teilweise auch zur Laufzeit. (z.B.: DIV und MOD funktionieren deshalb, bei älteren Compilern, auch nicht richtig) |
Re: UInt64 Typ-Problem bei Vorgabewerten
Es handelt sich wie schon gesagt um Delphi2007.
Das kann ja wohl nicht sein, dass hier UInt64 noch fehlerhaft implementiert ist, oder ??? Wie sieht das bei Delphi 2009 aus? Kann das mal jemand probieren bitte? |
Re: UInt64 Typ-Problem bei Vorgabewerten
Da bekomm ich erstmal folgenden Fehler bei Max und Min,
da es kein Max/Min für UInt64, in der Unit Math, gibt und er daher auf die nächst möglichen Datentyp für UInt64 ausweicht, also Double (da dort der Wertebereich reinpaßt). Nja und da dann der Typ Double ist, kann er an Result(UInt64) nicht übergeben werden :stupid: Zitat:
soo, also in D2009 kompiliert dieses nun erfolgreich und ohne Compilermeldungen.
Delphi-Quellcode:
[add]
program Project1;
{$APPTYPE CONSOLE} uses SysUtils, Math; function StrToU64(const S:String; aDefault:UInt64=0; aMin:UInt64=Low(UInt64); aMax:UInt64=High(UInt64)): UInt64; var E: Integer; begin Val(S, Result, E); if E <> 0 then Result := aDefault else if Result < aMin then Result := aMin else if Result > aMax then Result := aMax; end; var MyU64: UInt64; begin MyU64 := StrToU64('123'); if MyU64 = 0 then ; end. hab grad aber etwas bemerkt ... Val funktioniert nicht begin MyU64 := StrToU64('18446744073709551615'); if MyU64 = 0 then ; end.[/delphi] hier liefert er statt 18446744073709551615 (MaxUInt64) nur 1844674407370955161 und meckert an der letzen Stelle rum ... ich fürchte da hat sich auch ein Int64 in Val eingeschlichen aber MyU64 := StrToU64('$FFFFFFFFFFFFFFFF'); funktioniert perfekt ... also hab ich schon richtig gleich von Haus aus in meiner XML-Klasse richtig gemacht, da alles außerhalb Int64 nach Hex konvertiert wird :angel2: |
Re: UInt64 Typ-Problem bei Vorgabewerten
Hmm, ich habe natürlich Min/Max als UInt64 überladen, damit alles UInt64 ist und auch bleibt.
Delphi-Quellcode:
@himitsu: Offensichtlich lässt sich der Code bei Dir im Delphi2009 aber kompilieren ohne das Setzen der Grenzwerte von StrToU64(). Das ist ja schon mal eine Verbesserung! Aber Du hast recht, Val geht auch nicht in Delphi2007. Die RTL kennt nur eine Implementierung für Int64 ...
function Min(const A, B: UInt64): UInt64; overload;
function Max(const A, B: UInt64): UInt64; overload; function Min(const A, B: UInt64): UInt64; begin if A < B then Result := A else Result := B; end; function Max(const A, B: UInt64): UInt64; begin if A > B then Result := A else Result := B; end;
Delphi-Quellcode:
... welche dann bei Aufruf mit StrToU64('$FFFFFFFFFFFFFFFF', ..) eine Bereichsüberschreitung ergibt.
function _ValInt64(const s: AnsiString; var code: Integer): Int64;
Irgendwie ist das echter Mist, wenn man keine unsigned 64 Werte verarbeiten kann :cry: |
Re: UInt64 Typ-Problem bei Vorgabewerten
man kann schon .... man muß halt nur ab und zu mal etwas umbiegen, verbiegen, umleiten und tricksen :angel2:
|
Re: UInt64 Typ-Problem bei Vorgabewerten
Für die Übergabe von Strings in Hex-Darstellung genügt es, wenn man die Bereichsüberprüfung bei der Val-Funktion abschaltet:
Delphi-Quellcode:
Bei Strings in Dezimaldarstellung klappt das aber nicht. Hier muss eine eigene Val her:
{$R-}
Val(S, Result, E); {$R+}
Delphi-Quellcode:
Man beachte, dass es auch hier nötig ist, die Bereichsprüfung für das Aufsummieren des Results abzuschalten.
function ValUInt64(const s: AnsiString; var code: Integer): UInt64;
var i,l: Integer; dig: Integer; empty: Boolean; begin l := Length(s); i := 1; dig := 0; Result := 0; if s = '' then begin code := i; exit; end; while s[i] = ' ' do Inc(i); if s[i] = '+' then Inc(i); empty := True; if (s[i] = '$') or (Upcase(s[i]) = 'X') or ((s[i] = '0') and (Upcase(s[i+1]) = 'X')) then begin if s[i] = '0' then Inc(i); Inc(i); while True do begin case s[i] of '0'..'9': dig := Ord(s[i]) - Ord('0'); 'A'..'F': dig := Ord(s[i]) - (Ord('A') - 10); 'a'..'f': dig := Ord(s[i]) - (Ord('a') - 10); else break; end; {$R-} Result := Result shl 4 + dig; {$R+} if (l<i+1) then break; Inc(i); empty := False; end; end else begin while True do begin case s[i] of '0'..'9': dig := Ord(s[i]) - Ord('0'); else break; end; {$R-} Result := Result*10 + dig; {$R+} if (l<i+1) then break; Inc(i); empty := False; end; end; if (s[i] <> #0) or empty then code := i else code := 0; end; Mir düngt so langsam, dass intern UInt64=Int64 ist. :?: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:23 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