Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi HEX-string (Zweierkomplement) in Dezimal-string wandeln (https://www.delphipraxis.net/65991-hex-string-zweierkomplement-dezimal-string-wandeln.html)

MarLe 23. Mär 2006 09:54


HEX-string (Zweierkomplement) in Dezimal-string wandeln
 
... und umgekehrt.

Delphi-Quellcode:
var sHex: string;
    iDez: integer;
begin
  sHex:='$93E0';
  iDez:=StrToInt(sHex);
end;
... funktioniert bei der Darstellung im Zweierkomplement nicht
weil z.B. $93E0 = -27680 ergibt.

Mein Gedanke, den String in eine Binärzahl wandeln, das Highbit rausziehen, Vorzeichen auswerten,
invertieren und einen Einser addieren und dann wieder wandeln.

Hat das vielleicht schon jemand mal umgesetzt oder bin ich auf der falschen Fährte?

Hawkeye219 23. Mär 2006 10:00

Re: HEX-string (Zweierkomplement) in Dezimal-string wandeln
 
Deklariere iDez mal als SmallInt...

Gruß Hawkeye

chrisw 23. Mär 2006 10:01

Re: HEX-string (Zweierkomplement) in Dezimal-string wandeln
 
Bei mir funktioniert das :

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var sHex: string;
    iDez: integer;
begin
  sHex:='$93E0';
  iDez:=StrToint(sHex);
  showmessage(inttostr(iDez)); // ergibt 37856
end;

marabu 23. Mär 2006 10:09

Re: HEX-string (Zweierkomplement) in Dezimal-string wandeln
 
Wenn man statt Integer einen vorzeichenlosen Typen (Word oder Cardinal) nimmt, dann gibt es auch keine Probleme.

Grüße vom marabu

Hawkeye219 23. Mär 2006 10:15

Re: HEX-string (Zweierkomplement) in Dezimal-string wandeln
 
Mit seinem Quelltext erhält er bereits ein positives Ergebnis (getestet mit Delphi 2006).
Ich denke, daß er ein negatives Ergebnis erwartet.

Gruß Hawkeye

marabu 23. Mär 2006 10:22

Re: HEX-string (Zweierkomplement) in Dezimal-string wandeln
 
Hallo Hawkeye,

ich hatte die Frage so verstanden, dass aufgrund des gesetzten Highbit im HexString und die Verwendung von Integer (in D1 oder durch Typverbiegung 16bit) fälschlicherweise ein negativer Wert geliefert wird. Egal, wie es gemeint war, jetzt liegen ja alle eventuellen Lösungen vor...

marabu

MarLe 23. Mär 2006 10:31

Re: HEX-string (Zweierkomplement) in Dezimal-string wandeln
 
Ich erwarte ein negatives Ergebnis.

@chrisw
$93E0 ergibt nicht 37856 sonder in der Zweierkomplement-Darstellung -27680 !!!

@Hawkeye219
Vom Wertebereich würde es passen.
SmallInt 16Bit mit Vorzeichen von +32767/-32768

Ich probier mal den Vorschlag von @marabu

MarLe 23. Mär 2006 10:38

Re: HEX-string (Zweierkomplement) in Dezimal-string wandeln
 
Delphi-Quellcode:
var sHex: string;
    iDez: smallint;
begin
  sHex:='$93E0';
  iDez:=StrToInt(sHex);
  ShowMessage(IntToStr(iDez));
end;
... haut nicht hin.
Meldung: Konstantenausdruck verletzt untere Grenze

Wenn ich iDEZ als longint deklariere bekomm ich wieder den falschen Wert 37856 ?!?

Sharky 23. Mär 2006 10:42

Re: HEX-string (Zweierkomplement) in Dezimal-string wandeln
 
Hmmm.... Delphi arbeitet doch mit dem Einerkomplement oder?
Wenn ich nun einen HEX-String habe von dem ich weiss das er eine Darstellung im Zweierkomplement ist muss ich das doch umrechnen:
Delphi-Quellcode:
procedure TDemoForm.Button1Click(Sender: TObject);
var
  sHex: string;
  iDez: integer;
  neg : boolean;
begin
  sHex := '$93E0';
  iDez := StrToint(sHex);
  neg := (iDez AND $8000) = $8000;
  dec(iDez);
  iDez := iDez XOR $FFFF;
  if (neg) then
    iDez := iDEZ * -1;

  showmessage(inttostr(iDez)); // ergibt 37856
end;

MarLe 23. Mär 2006 10:54

Re: HEX-string (Zweierkomplement) in Dezimal-string wandeln
 
@Sharky
Das war auch mein Gedanke, Danke für die Bestätigung.
Dein Code funktioniert richtig

Delphi-Quellcode:
showmessage(inttostr(iDez)); // ergibt -27680
Hast du vielleicht auch noch gleich eine Lösung für den umgekehrten Weg,
von Dezimal nach Hex im Zweierkomplement?

Sharky 23. Mär 2006 11:05

Re: HEX-string (Zweierkomplement) in Dezimal-string wandeln
 
Zitat:

Zitat von MarLe
... Hast du vielleicht auch noch gleich eine Lösung für den umgekehrten Weg,
von Dezimal nach Hex im Zweierkomplement?

Der Weg von Dez -> Zweierkompliment ist ja:
  1. Zahl als Betrag (also ohne Vorzeichen)
  2. Bits invertieren
  3. Zahl um 1 erhöhen

Ergo müsste es so sein:
Delphi-Quellcode:
procedure TDemoForm.Button2Click(Sender: TObject);
var
  sHex: string;
  iDez: integer;
  neg : boolean;
begin
  iDez := -27680;
  neg := iDez < 0;
  if (neg) then
   iDez := iDez * -1; // In Betrag wandeln
  iDez := iDez XOR $FFFF; // Invertieren
  INC(iDez); // Um 1 erhöhen.
  sHex := IntToHex(iDez,4);
  showmessage(sHex);
end;
Das ganze kann/sollte man natürlich noch etwas opimieren. Ich wollte nur die einzelnen schritte zeigen.

MarLe 23. Mär 2006 12:02

Re: HEX-string (Zweierkomplement) in Dezimal-string wandeln
 
Vielen Dank - funktioniert perfekt

Hawkeye219 23. Mär 2006 12:33

Re: HEX-string (Zweierkomplement) in Dezimal-string wandeln
 
@Sharky
Delphi arbeitet mit dem Zweierkomplement:
Delphi-Quellcode:
+1 = 0000...0001
-1 = 1111...1111
Laut Wikipedia wird das Einerkomplement bei der Ganzzahlarithmetik nicht verwendet, weil es einige Nachteile mit sich bringt. Unter anderem gibt es für die Null zwei Binärdarstellungen.

@MarLe
Die Fehlermeldung konnte ich mit eingeschalteter Bereichsprüfung nachvollziehen. Seltsamerweise tritt der Fehler nicht auf, wenn man statt StrToInt() die Prozedur Val() verwendet. Das Ergebnis ist auch in diesem Fall korrekt.

MarLe 23. Mär 2006 13:02

Re: HEX-string (Zweierkomplement) in Dezimal-string wandeln
 
Das ganze funktioniert auch nicht richtig wenn ich den Hex-Wert
über ein Eingabefeld (TEdit) übergebe:

Delphi-Quellcode:
sHex := '$93E0';        // ergibt -27680
sHex := EditsHex.Text;  // eine Eingabe von $93E0 ergibt 37856 ?!?
Sorry, funktioniert schon, aber nur bei negativen Werten (siehe nächsten Beitrag)

MarLe 23. Mär 2006 14:32

Re: HEX-string (Zweierkomplement) in Dezimal-string wandeln
 
Die Funktionen rechnen nur bei negativen Werten richtig.

Delphi-Quellcode:
Hex2Dec:
$55C8 -> 43576 falsch
$007F -> 65409 falsch
$0001 -> 65535 falsch
$FFFF -> -1 richtig
$FFF0 -> -16 richtig

Dec2Hex:
+21960 -> $AA2F falsch
  +127 -> $FF81 falsch
    +1 -> $FFFF falsch
    -1 -> $FFFF richtig
   -16 -> $FFF0 richtig

korrekte Werte wären:
$55C8 <-> +21960
$007F <-> +127
$0001 <-> +1
$FFFF <-> -1
$FFF0 <-> -16
Ich denke mal ich muss bei Hex2Dec vorher das Highbit (0 oder 1) auswerten.
Bei Dec2Hex das Vorzeichen, oder???

Hawkeye219 23. Mär 2006 15:03

Re: HEX-string (Zweierkomplement) in Dezimal-string wandeln
 
Versuch's mal damit:
Delphi-Quellcode:
function Dec2Hex (aValue: integer): string;
begin
  Result := IntToHex(LoWord(aValue), 4);
end;

function Hex2Dec (const aValue: string): Integer;
  var code : Integer;
      temp : SmallInt;
begin
  Val (aValue, temp, code);
  Result := temp;
end;
Die Routinen liefern/erwarten 4-stellige Hexwerte und führen keine Fehlerüberprüfung durch.

Gruß Hawkeye

MarLe 23. Mär 2006 15:34

Re: HEX-string (Zweierkomplement) in Dezimal-string wandeln
 
Vielen Dank, funktioniert.

Wie haut das bei 2- bzw. 8 stelligen Hex-Werten hin.
Hängt das Ergebnis der Funktion val() von der Deklaration der Variablen ab?
(SmallInt, ShortInt bzw. LongInt)

Hawkeye219 23. Mär 2006 15:42

Re: HEX-string (Zweierkomplement) in Dezimal-string wandeln
 
Ja, scheint so zu sein.
Bei Dec2Hex nimmst Du dann Lo() für 2-stellige Hexwerte.

Gruß Hawkeye

MarLe 23. Mär 2006 15:51

Re: HEX-string (Zweierkomplement) in Dezimal-string wandeln
 
Hätte ich jetzt auch gedacht. Aber
Delphi-Quellcode:
Result := IntToHex(LoWord(aValue), 2);
liefert bei -40 $FFD8

Hawkeye219 23. Mär 2006 15:54

Re: HEX-string (Zweierkomplement) in Dezimal-string wandeln
 
Lo(), nicht LoWord() :zwinker:


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:14 Uhr.

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