Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi 2x Cardinal => 1x int64 (https://www.delphipraxis.net/135263-2x-cardinal-%3D-1x-int64.html)

Weazy 8. Jun 2009 01:26


2x Cardinal => 1x int64
 
Hallo, ich habe zwei Cardinal Werte welche zu einem int64 verschmelzen sollen. Der eine Cardinal enthält die ersten 32 Bits, der andere Cardinal die unteren 32 Bits des int64. Hier mal ein erster Versuch:

Delphi-Quellcode:
function CardToInt64(const high,low:cardinal):int64;
begin
  Result:=0; //mit 0 auffüllen
  Result:=high shl 32; //obere 4 Bytes setzten
  Result:=Result or low; // untere 4 Bytes setzten
end;
Leider scheint das verschieben mit shl nicht so ganz zu funktionieren, laut hilfe soll das nur für 32 bit integers funktionieren, wie könnte ich das hinbekommen? Die eignetliche Frage ist eigentlich nur wie ich "high" in der oberen Bereich des Resultats bekomme und ob es ev eine bessere Methode gibt?!?

Dax 8. Jun 2009 02:00

Re: 2x Cardinal => 1x int64
 
Delphi-Quellcode:
function CardToInt64(const high,low:cardinal):int64;
begin
  Result:=int64(high) shl 32 or low;
end;

Neutral General 8. Jun 2009 06:50

Re: 2x Cardinal => 1x int64
 
Hi,

Noch eine kleine Aufklärung warum deine function nicht funktioniert:

Delphi-Quellcode:
Result:=high shl 32;
der Ausdruck wird von rechts nach links ausgewertet. high ist ein Cardinal. Wenn du einen 32-Bit Integer 32 Stellen nach links (oder rechts) verschiebst, dann bleibt 0 übrig..

00000000000000000000000000000000 11111111111111111111111111111111

shl 32

11111111111111111111111111111111 00000000000000000000000000000000

Der Linke Teil, also der Cardinal wird dann in einen Int64 konvertiert (implizit):

00000000000000000000000000000000 00000000000000000000000000000000

Und das mit low "verodert" ergibt eben low ;)

Gruß
Neutral General

uligerhardt 8. Jun 2009 08:19

Re: 2x Cardinal => 1x int64
 
Ungetestet:
Delphi-Quellcode:
uses SysUtils;

Int64Rec(AInt64).Hi := ACard1;
Int64Rec(AInt64).Lo := ACard2;

hoika 8. Jun 2009 08:28

Re: 2x Cardinal => 1x int64
 
Hallo,

sowas riecht nach variant record

Delphi-Quellcode:
type
  Tvar_rec = packed record
    case i: Integer of
      0:
       (
          _card_low : Cardinal;
          _card_high : Cardinal;
       );
      1:
       (
        _int64: Int64;
       );
    end;

var
  rec: Tvar_rec;
begin
  rec._int64:= 12345;

  rec.card_low // auslesen oder setzen
  rec.card_high // auslesen oder setzen
weitere Infos dazu unter
records in Delphi

<Update>:
Oder den vordefinierten int64Rec benutzen, wie mein Vorgänger schon gezeugt hat ...


Heiko
PS: habs nicht getestet, vielleicht muss low und high noch vertauscht werden.

Weazy 8. Jun 2009 11:09

Re: 2x Cardinal => 1x int64
 
Danke für die Antworten! man merkt wohl das es gestern (heute) wieder mal spät wurde, ansonsten hätte ich das mit dem shl wohl geklärt;-)

himitsu 8. Jun 2009 11:19

Re: 2x Cardinal => 1x int64
 
Zitat:

Zitat von hoika
PS: habs nicht getestet, vielleicht muss low und high noch vertauscht werden.

nee, ist schon OK so ... in Windows fängt alles klein an und wird dann nach hinten immer größer :)

mkinzler 8. Jun 2009 11:39

Re: 2x Cardinal => 1x int64
 
Zitat:

nee, ist schon OK so ... in Windows fängt alles klein an und wird dann nach hinten immer größer Smile
Little-Endian halt :zwinker:
http://de.wikipedia.org/wiki/Byte-Reihenfolge

himitsu 17. Aug 2009 19:24

Re: 2x Cardinal => 1x int64
 
mir ist grad in einem Projekt etwas eigenartiges aufgefallen und ich konnte es jetzt auf 2 PCs genauso nachvollziehen.

Delphi-Quellcode:
var i, j: Integer;
  k: Int64;
begin
  i := 123;
  j := 456;
  k := (i shl 32) or j;
eigentlich müßte hier ja i3 = 456 sein, da wie Neutral General in Beitrag #3 schon richtig erklärte, der Wert von i aus dem Wertebereich rausverschoben werden sollte, ABER

ich bekomme 507 raus, also quasi
Delphi-Quellcode:
k := i or j;
laut Debugger stimmt dieses tatsächlich, da der Wert von i, trotz erfolgreich ausgeführtem SHL-Befehl, im entsprechendem Register garnicht verändert wird. :shock:


[add] ach ja, hab hier einen kleinen Athlon64 drinnen
und ein WinXP SP3 mit 32 Bit

Apollonius 17. Aug 2009 19:36

Re: 2x Cardinal => 1x int64
 
Man lese die Intel-Handbücher und staune:
Zitat:

The count is masked to 5 bits (or 6 bits if in 64-bit mode and REX.W is used).


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:46 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