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 TSmallPoint (TPoint sind 2 Integer in einem Int64)
// 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 Cantorsche Paarungsfunktion (mit der man sogar beliebig viele natürliche Zahlen auf eine einzige umkehrbar abbilden kann).
http://upload.wikimedia.org/math/7/9...63de70c533.png 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: http://upload.wikimedia.org/math/e/3...20ce9955d8.png http://upload.wikimedia.org/math/8/0...db720a87fe.png 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 04:48 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