![]() |
Zwei Werte [0..16] in einem Integer festhalten
Hallo!
Ich habe gerade ein kleines Problem: Und zwar soll ich zwei Werte in einem Integer festhalten. Die Werte liegen zwischen MIN_X..MAX_X und MIN_Y..MAX_Y (im konkreten Beispiel jeweils zwischen 1 und 16, das soll aber variabel bleiben). Nun stehe ich total auf dem Schlauch! Gibt es eine mathematische Lösung für das Problem? Wäre aber auch mit einer Idee für eine Q&D Lösung zufrieden, da ich echt keine Ahnung habe... Gruß! |
Re: Zwei Werte [0..16] in einem Integer festhalten
Wie wäre es mit dem Datentyp TPoint?
|
Re: Zwei Werte [0..16] in einem Integer festhalten
Zitat:
|
Re: Zwei Werte [0..16] in einem Integer festhalten
Entweder du löst das Mathematisch
Delphi-Quellcode:
oder über einen Record ... analog zu
// setzen
G := A * 100 + B; // auslesen A := G div 100; B := G mod 100; ![]()
Delphi-Quellcode:
oder
type
TSplitt = record case Integer of 0: (g: LongInt); 1: (a, b: Word); end; // setzen Splitt.a := A; Splitt.b := B; g := Splitt.g; // auslesen Splitt.g := G; A := Splitt.a; B := Splitt.b; // auslesen A := TSplitt(G).a; B := TSplitt(G).b;
Delphi-Quellcode:
Das Ganze kann man notfalls noch in Funktionen kapseln:
type
TSplitt = record class function Set(A, B: Word): LongInt; case Integer of 0: (g: LongInt); 1: (a, b: Word); end; class function TSplitt.Set(A, B: Word): LongInt; begin TSplitt(Result).a := A; TSplitt(Result).b := B; end: // setzen TSplitt(G).a := A; TSplitt(G).b := B; // setzen G := TSplitt.Set(A, B); // auslesen Splitt.g := G; A := Splitt.a; B := Splitt.b; // auslesen A := TSplitt(G).a; B := TSplitt(G).b; Typgrößen und Multiplikatoren können/müssen natürlich noch angepaßt werden. |
Re: Zwei Werte [0..16] in einem Integer festhalten
Dank der Unendlichkeit der natürlichen Zahlen ist dies tatsächlich einwandfrei mathematisch lösbar, bekannt als
![]() ![]() Beispiel: du willst (5,3) speichern. Das wäre dann einfach ((5 + 3) * (5 + 3 + 1)) / 2 + 3 = 39. Zur Umkehrung benötigt man zwei Funktionen: ![]() ![]() Zunächst sucht man nun (durch ausprobieren?) die größte Zahl i (oben dargestellt durch die Funktion q), für die gilt f(i) <= 39. i ist in unserem Fall 8. Dann ist y = 39 - f(8) = 39 - 36 = 3. x ergibt sich aus i - y = 8 - 3 = 5. Noch Fragen :mrgreen: ? edit: und unter o.g. Link findet man sogar noch Pascal-Code für die Umkehrfunktion:
Delphi-Quellcode:
procedure CantorPair( I : Integer;
Var X,Y : Integer); { Gibt das i-te Paar (X,Y) in Diagonalabzaehlung zurueck } var J : Integer; function F(Z : Integer) : Integer; begin F := Z * (Z + 1) div 2 end; function Q(Z : Integer) : Integer; var V : Integer; begin V := 0; while F(V) <= Z do V := V + 1; Q := V - 1 end; begin J := Q(I); Y := I - F(J); X := J - Y; end; |
Re: Zwei Werte [0..16] in einem Integer festhalten
@himitsu: Vielen Dank für deine vielen schnellen Ideen!
Ich habe es jetzt auf die mathematische Weise gelöst: Setzen:
Delphi-Quellcode:
Auslesen:
MyInt := X * Max(MAX_X, MAX_Y) + Y;
Delphi-Quellcode:
@Meflin: Nein, keine weiteren Fragen :wink:
X := MyInt div Max(MAX_X, MAX_Y);
Y := MyInt mod Max(MAX_X, MAX_Y); Danke nochmal! |
Re: Zwei Werte [0..16] in einem Integer festhalten
Es müßte wohl mehr so aussehn:
MAX_Y+1 ist ja der kleinste Wert, in dessen Vielfachen X liegen muß, so daß Y noch reinpaßt. Setzen:
Delphi-Quellcode:
Auslesen:
MyInt := X * (MAX_Y + 1) + Y;
Delphi-Quellcode:
X := MyInt div (MAX_Y + 1);
Y := MyInt mod (MAX_Y + 1); und falls MIN_Y auch negativ sein kann: Setzen:
Delphi-Quellcode:
Auslesen:
MyInt := X * (Max(MAX_Y, Abs(MIN_Y)) + 1) + Y;
Delphi-Quellcode:
X := MyInt div (Max(MAX_Y, Abs(MIN_Y)) + 1);
Y := MyInt mod (Max(MAX_Y, Abs(MIN_Y)) + 1); |
Re: Zwei Werte [0..16] in einem Integer festhalten
Du könntest die beiden Werten auf jeweils im High- und Low-Word speichern. 1..16 könntest du sogar 4 mal in einem Integer unterbringen, wenn ich dich nicht falsch verstanden hab.
|
Re: Zwei Werte [0..16] in einem Integer festhalten
@divBy0: 1..16 paßt sogar bis zu 8 Mal in einen Interger rein.
bzw. ein Integer (4-Byte) läßt sich mit 8 Hexadezimalstellen (Base16) darstellen. |
Re: Zwei Werte [0..16] in einem Integer festhalten
So kleine Werte lassen sich in einem einzigen Byte speichern:
1..16 (0..15) = 1 Nibble 2 Nibble = 1 Byte Weil man mit Integern rechnet, kann man gut damit umgehen: var numberByte: integer; highNibble,lowNibble: integer; (Byte:=16*highNibble + lowNibble;) numberByte:=16*highNibble + lowNibble; highNibble:=numberByte div 16; lowNibble:=numberByte mod 16; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:06 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