AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign kleine Datentypen (BYTE) zusammenfassend als z.B. WORD/Integer übergeben
Thema durchsuchen
Ansicht
Themen-Optionen

kleine Datentypen (BYTE) zusammenfassend als z.B. WORD/Integer übergeben

Ein Thema von Amicello · begonnen am 14. Okt 2024 · letzter Beitrag vom 14. Okt 2024
Antwort Antwort
Seite 1 von 2  1 2      
Amicello

Registriert seit: 12. Sep 2016
13 Beiträge
 
#1

kleine Datentypen (BYTE) zusammenfassend als z.B. WORD/Integer übergeben

  Alt 14. Okt 2024, 15:07
Hallo...

ich suche nach einem eleganten Weg - vielleicht kann hier jemand weiterhelfen.
Ich versuche das mal irgendwie verständlich zu erklären.

Beispielsituation:
Es gibt 2 Parameter als kleine Dateitypen - z.B. x/y Koordinatenpaare als Byte (0..255)

Theoretisch könne man diese zu einem 16-bit Word zusammensetzen - und praktischerweise
als eine einzige Variable benutzen um sie Funktionen zu übergeben und/auch als Erbegnis zu erhalten.


So in der Art:

Code:
Function       Mittelpunkt(coord1,coord2:TCombinedCoord):TCombinedCoord;
        begin   result.x := (coord1.x + coord2.x) shr 1;
                result.y := (coord1.y + coord2.y) shr 1;
        end;

Sprich die Funktion bekommt nur zwei WORD's geliefert, rechnet aber mit dem Byte-Anteilen,
und liefert dann ein kombiniertes WORD des Koordinatenpaares zurück.


Verwenden würde ich das dann am liebsten so:

Code:
MeinMittelpunkt := Mittelpunkt( startpunkt, endpunkt );
MeinMittelpunkt := Mittelpunkt( (x1,y1), (x2,y2) );
MeinMittelpunkt := Mittelpunkt( (14,52), (29,151) ); // wäre toll, wenn das so geht


Str := 'Mittlere x-Koordinate: ' + i2s(MeinMittelpunkt.x);

Ich hoffe das war so im Groben verstöndlich.
Kann man da mit packet record o.ä. etwas Elegantes tricksen?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.934 Beiträge
 
Delphi 12 Athens
 
#2

AW: kleine Datentypen (BYTE) zusammenfassend als z.B. WORD/Integer übergeben

  Alt 14. Okt 2024, 15:25
Für 2 Word zu einem Integer gibt es Delphi-Referenz durchsuchenMakeLong, bzw. MakeULong ... und zurück via HiWord und LoWord.

Oder man nimmt Records,
entweder zum Speichern (noch ein paar ImpliciteCasts und 'nen Constructor dran und die lassen sich super nutzen)
oder zum Casten, wie z.B. Delphi-Referenz durchsuchenWordRec.

Oder den Delphi-Referenz durchsuchenTWordHelper am Word-Typen, aber leider fehlen bei den Delphi-Helper für Byte/Word/usw. die nötigen ZugriffsProperty.
z.B. bei Single/Double/Extended kann man via MySingleVar.Bytes[0] lesend und schreibend auf die Eintelteile zugreifen.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (14. Okt 2024 um 15:27 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von dummzeuch
dummzeuch
Online

Registriert seit: 11. Aug 2012
Ort: Essen
1.586 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#3

AW: kleine Datentypen (BYTE) zusammenfassend als z.B. WORD/Integer übergeben

  Alt 14. Okt 2024, 17:02
Was willst Du damit erreichen? Speicher sparen? Klar geht das, aber bei vielen Werten geht das dann ziemlich auf die Performance und nicht zuletzt auf die Lesbarkeit / Debugbarkeit.

Ich würde dann vermutlich ein
Delphi-Quellcode:
type
  TCombinedCoord = packed record
  var integer of // <= das belegt keinen Speicher
    0: (AsWord: Word);
    1: (x, y: Byte);
  end;
Einen solchen Record kann man dann auch noch mit ein paar Methoden schmücken:
Delphi-Quellcode:
type
  TCombinedCoord = packed record
    // Methoden müssen vor dem VAR-Part deklariert werden
    class function From(_x, _y: byte): TCombinedCoord; static;
  var integer of
    0: (AsWord: Word);
    1: (x, y: Byte);
  end;
So dass man z.B. folgendes schreiben könnte:

MeinMittelpunkt := Mittelpunkt(TCombinedRecord.From(x1,y1), TCombinedRecord.From(x2,y2));
Ob das aber soviel besser ist?

Lesbarer wäre definitiv eine normale Funktion statt einer Methode:

MeinMittelpunkt := Mittelpunkt(Combine(x1,y1), Combine(x2,y2));
Thomas Mueller

Geändert von dummzeuch (14. Okt 2024 um 17:04 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.934 Beiträge
 
Delphi 12 Athens
 
#4

AW: kleine Datentypen (BYTE) zusammenfassend als z.B. WORD/Integer übergeben

  Alt 14. Okt 2024, 17:38
Ach ja, da es X/Y-Koordinaten sind, würde ich, falls ich einen Record nutze, eher versuchen etwas Vorhandenes zu verwenden, also z.B.
TSmallPoint (2*SmallInt)
TPoint (2*LongInt)
TPointL (2*Longint)
TPointfx (Word+SmallInt)
TPointFloat (2*Single)
TPair<Byte,Byte>
...


Aber normal werwende ich sowas nur, wenn ich Daten in/durch eine bestehende Struktur quetschen muß.
z.B. bei Memos und ScrollBars, wo Anfang+Ende oder X/Y-CursorPos als "ein" LPARAM ins SendMessage rein muß. (siehe MakeLong)

Oder wo ich eine Funktion hab, welche nicht überladen werden kann, aber unterschiedliche Typen bekommen soll.
In ältern Delphis z.b. für ein Named-Array, wo das Index-Property mit Index oder Name genutzt werden sollte, wo der Index-PropertyTyp also ein Record mit AutoCast war, welcher String und Integer als Parameter entgegennimmt.

Sonst versucht ich möglichst schon die Eingabe einfach zu machen und sowas mir zu ersparen-
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (14. Okt 2024 um 17:44 Uhr)
  Mit Zitat antworten Zitat
Amicello

Registriert seit: 12. Sep 2016
13 Beiträge
 
#5

AW: kleine Datentypen (BYTE) zusammenfassend als z.B. WORD/Integer übergeben

  Alt 14. Okt 2024, 18:44
Da verneige ich mich doch gleich mal in Richtung Essen und Japan für die perfekten Antworten.
Nach einem schon existierenden TPoint/TPair zu suchen - auf so etwas Simples bin ich gar nicht gekommen.
Wieder was gelernt!

Bei Packed Records hat mich immer der "Integer of" Teil verwirrt:
Sprich wo liegt dieses Integer, wann wird es im Code abgefragt, ist das nicht unnötig und was bedeuten die Werte..
Dein "<= das belegt keinen Speicher" interpretiere ich jetzt mal so, dass man das einfach ignorieren kann -
weil Delphi das weder anlegt noch auswertet sondern "nur einfach so" geschrieben haben möchte. Richtig?


"Was willst Du damit erreichen?"
Immer zwei Variablen für x/y seperat zu übergeben fand ich umständlich.
Zu dem gehören die für mein Verständnis ja auch logisch zu einer Einheit.

Habt mir sehr weitergeholfen!

Merci

Geändert von Amicello (14. Okt 2024 um 18:46 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.934 Beiträge
 
Delphi 12 Athens
 
#6

AW: kleine Datentypen (BYTE) zusammenfassend als z.B. WORD/Integer übergeben

  Alt 14. Okt 2024, 19:28
Delphi-Quellcode:
MeinMittelpunkt := Mittelpunkt(MakeLong(x1,y1), MakeLong(x2,y2));

MeinMittelpunkt := Mittelpunkt(Point(x1,y1), Point(x2,y2));
MeinMittelpunkt := Mittelpunkt(TPoint.Create(x1,y1), TPoint.Create(x2,y2));
Wenn es nur ums Übergeben geht, dann ist MakeLong eher ungünstig, da die Werte beim Debuggen ja erst im Kopf wieder zerlegt werden müssen (Ansicht der Variable als HEX wäre einen Hauch hilfreich)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.685 Beiträge
 
Delphi 2007 Enterprise
 
#7

AW: kleine Datentypen (BYTE) zusammenfassend als z.B. WORD/Integer übergeben

  Alt 14. Okt 2024, 21:59
Bei Packed Records hat mich immer der "Integer of" Teil verwirrt:
Da vermischt du zwei Dinge:
Packed Records sind eigentlich ganz normale Records. Üblicherweise werden die im Speicher (je nach eingestellter Compiler-Option, aber ich gehe von der Voreinstellung aus) an den Wort-Grenzen der gewählten Prozessorarchitektur ausgerichtet (aktuell also 32- oder 64-Bit Wortbreite). Heisst, dass selbst wenn du in einem Record nur ein Byte deklarierst, wird ein nachfolgendes Byte nicht ein Byte weiter im Speicher liegen, sondern ein DWORD oder QWORD weiter.
Wenn du nun einen Record als "packed" deklarierst, wirft der Compiler das über Bord, und das zweite Byte wird tatsächlich nur ein Byte später im Speicher stehen.
Grund ist, dass es üblicherweise schneller und effizienter ist, immer so auf den Speicher zuzugreifen, dass man sich immer an den "natürlichen" Grenzen der Architektur orientiert. Anderenfalls muss hinter den Kulissen immer etwas "gepflückt und geschubst" werden - entweder vom Compiler, oder die CPU macht das selber. Kostet aber halt immer Taktzyklen.
Daher sollte man einen Record nur dann packed deklarieren, wenn es essenziell wichtig ist, dass im Speicher nachher alle Felder des Records dicht an dicht liegen. Ein paar Bytes hier und da "sparen" rechtfertigt das heutzutage meiner Meinung nach nicht mehr.

Das andere sind "Variante Records":
Das ist eine etwas verwirrende Schreibweise, da Delphi sonst kein Vokabular hat, um unterschiedliche Namen für den selben Speicherbereich zu deklarieren. Du sagst hier am Ende nur: Es gibt ein Integer-langes Stück Speicher, und es folgt eine Liste von ebenfalls jeweils insgesamt Integer-langen deklarationen, unter dessen Namen man wahlweise auf diesen Bereich (oder Teilen von diesem) später zugreifen kann.
Die gezeigte Deklaration sagt also:
1) Es gibt ein Stück Speicher der Länge SizeOf(Integer) (was hier allerdings falsch wäre, es müsste "Word" benutzt werden!)
2) Du kannst das ganze Word unter dem Namen "AsWord" erreichen.
3) Du kannst alternativ das erste Byte desselben Words unter dem Namen "x", das andere "y" erreichen.


Zitat:
"Was willst Du damit erreichen?"
Immer zwei Variablen für x/y seperat zu übergeben fand ich umständlich.
Zu dem gehören die für mein Verständnis ja auch logisch zu einer Einheit.

Habt mir sehr weitergeholfen!
Dafür sind definitiv Records, oder besser noch Klassen da! Wenn es dir rein um die "Semantik" geht, sind das die Werkzeuge - sie wurden genau dafür entwickelt!
Rumgefummel an/in internen Strukturen kann - in sehr spezifischen Einzelfällen(!) - Sinn machen, aber das sollte dann seeeehr gut begründet und dokumentiert sein. Deine Motivation würde ich hier keinesfalls als "guten Grund" ansehen können, weil es wie gesagt High-Level Mechanismen gibt, die ganz genau dafür da sind, und Lesbarkeit, Testbarkeit und Debugbarkeit sogar erhöhen, statt quasi komplett zu zerstören.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.571 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: kleine Datentypen (BYTE) zusammenfassend als z.B. WORD/Integer übergeben

  Alt 14. Okt 2024, 22:10
Das ist eine etwas verwirrende Schreibweise, da Delphi sonst kein Vokabular hat, um unterschiedliche Namen für den selben Speicherbereich zu deklarieren.
Nur der Vollständigkeit halber, das hat damit sonst nichts zu tun:
Doch, dafür gibt es absolute.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.934 Beiträge
 
Delphi 12 Athens
 
#9

AW: kleine Datentypen (BYTE) zusammenfassend als z.B. WORD/Integer übergeben

  Alt 14. Okt 2024, 22:40
Packed Records sind eigentlich ganz normale Records. Üblicherweise werden die im Speicher (je nach eingestellter Compiler-Option, aber ich gehe von der Voreinstellung aus) an den Wort-Grenzen der gewählten Prozessorarchitektur ausgerichtet (aktuell also 32- oder 64-Bit Wortbreite). Heisst, dass selbst wenn du in einem Record nur ein Byte deklarierst, wird ein nachfolgendes Byte nicht ein Byte weiter im Speicher liegen, sondern ein DWORD oder QWORD weiter.
Jo, Packed-Records sind einfach nur Records mit {$ALIGN 1}
maximale Ausrichtung an 1 Byte-Grenze

Gleichgroße Typen folgen immer einander.
folgt ein größerer Typ, dann wird er an "seiner" Größe ausgerichtet, oder maximal so viel, wie vorgegeben.

Also normal wird ein Word an 2 Byte ausgerichtet,
mit einer Lücke, wenn davor nur 1 Byte war.

Packed-Records oder Records mit einer definierten Ausrichtung braucht man nur, wenn der Records prozessübergreifend gespeichert/übertragen wird.

Innerhalb des selben Prozesses, ist es "optimaler", wenn ordentlich ausgerichtet wird, damit möglichst effizient auf den Speicher zugegriffen werden kann,
außer, es geht um maximale Speicher-Ersparnis. (meistens ist Effzienz aber das Wichtigere)


Zitat:
Integer of
Hier ist eigentlich CASE das wichtige Wort.
CASE OF

Dawzischen steht ein Typ, für die Zuordnung der CASES, welches auch eine "Variable" sein kann.
Delphi-Quellcode:
case Boolean of
  True: ( ... );
  False: ( ... );

case Char of
  'A': ( ... );
  'B': ( ... );

case Integer of
  0: ( ... );
  1: ( ... );

case Was: Integer of
  0: ( ... );
  1: ( ... );

// das Vorhergehende entspricht quasi Diesem, also mit einer Variable, in der man speichern kann (nicht muß), welcher Teil gültig ist.
Was: Integer;
case Integer of
  0: ( ... );
  1: ( ... );
Das nennt sich Variante-Records, also wo quasi verschiedene "Varianten" der Speicherbenennug übereinander liegen.
Auch andere Sprachen (C++) kennen sowas.
PS: Der Typ Variant nutzt intern sowas, um z.B. einen Integer oder einen String/PChar auf der selben Stelle zu speichern.

Das einzige Problem für Delphi ist, dass dem CASE das eigene END fehlt
und deswegen im Delphi/Pascal der Variante Block ausschließlich am Ende des Records stehen kann.
In C++ kann er auch mittendrin sein, was eine Konvertierung von Code nicht erleichtert.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (14. Okt 2024 um 22:50 Uhr)
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.685 Beiträge
 
Delphi 2007 Enterprise
 
#10

AW: kleine Datentypen (BYTE) zusammenfassend als z.B. WORD/Integer übergeben

  Alt 14. Okt 2024, 22:41
Das ist eine etwas verwirrende Schreibweise, da Delphi sonst kein Vokabular hat, um unterschiedliche Namen für den selben Speicherbereich zu deklarieren.
Nur der Vollständigkeit halber, das hat damit sonst nichts zu tun:
Doch, dafür gibt es absolute.
Ah okay, ich dachte das ist ein Spezialkonstrukt, dass nur in Siemens SCL existiert. Scheint aber nicht im Kontext von Record-Feldern zu gehen, vermutlich dann eher ein Relikt aus Turbo Pascal Zeiten oder?
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:37 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