AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Zwei Werte [0..16] in einem Integer festhalten

Zwei Werte [0..16] in einem Integer festhalten

Ein Thema von Jonelmeier · begonnen am 15. Mai 2010 · letzter Beitrag vom 17. Mai 2010
Antwort Antwort
Seite 1 von 2  1 2   
Jonelmeier

Registriert seit: 27. Sep 2007
Ort: Hamburg
96 Beiträge
 
Delphi XE Starter
 
#1

Zwei Werte [0..16] in einem Integer festhalten

  Alt 15. Mai 2010, 12:34
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ß!
Jonas
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie
(Moderator)

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Zwei Werte [0..16] in einem Integer festhalten

  Alt 15. Mai 2010, 12:36
Wie wäre es mit dem Datentyp TPoint?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Jonelmeier

Registriert seit: 27. Sep 2007
Ort: Hamburg
96 Beiträge
 
Delphi XE Starter
 
#3

Re: Zwei Werte [0..16] in einem Integer festhalten

  Alt 15. Mai 2010, 12:40
Zitat von Luckie:
Wie wäre es mit dem Datentyp TPoint?
Ich muss leider einen Integer zum speichern verwenden...das ist ja das Problem...
Jonas
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
38.604 Beiträge
 
Delphi 10.4 Sydney
 
#4

Re: Zwei Werte [0..16] in einem Integer festhalten

  Alt 15. Mai 2010, 12:41
Entweder du löst das Mathematisch

Delphi-Quellcode:
// setzen
G := A * 100 + B;

// auslesen
A := G div 100;
B := G mod 100;
oder über einen Record ... analog zu Delphi-Referenz durchsuchenTSmallPoint (TPoint sind 2 Integer in einem Int64)
Delphi-Quellcode:
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;
oder
Delphi-Quellcode:
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;
Das Ganze kann man notfalls noch in Funktionen kapseln:

Typgrößen und Multiplikatoren können/müssen natürlich noch angepaßt werden.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Benutzerbild von Meflin
Meflin

Registriert seit: 21. Aug 2003
4.856 Beiträge
 
#5

Re: Zwei Werte [0..16] in einem Integer festhalten

  Alt 15. Mai 2010, 13:00
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 ?

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;
Leo S.
  Mit Zitat antworten Zitat
Jonelmeier

Registriert seit: 27. Sep 2007
Ort: Hamburg
96 Beiträge
 
Delphi XE Starter
 
#6

Re: Zwei Werte [0..16] in einem Integer festhalten

  Alt 15. Mai 2010, 13:03
@himitsu: Vielen Dank für deine vielen schnellen Ideen!

Ich habe es jetzt auf die mathematische Weise gelöst:

Setzen:
MyInt := X * Max(MAX_X, MAX_Y) + Y; Auslesen:
Delphi-Quellcode:
X := MyInt div Max(MAX_X, MAX_Y);
Y := MyInt mod Max(MAX_X, MAX_Y);
@Meflin: Nein, keine weiteren Fragen

Danke nochmal!
Jonas
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
38.604 Beiträge
 
Delphi 10.4 Sydney
 
#7

Re: Zwei Werte [0..16] in einem Integer festhalten

  Alt 15. Mai 2010, 13:46
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:MyInt := X * (MAX_Y + 1) + Y; Auslesen:
Delphi-Quellcode:
X := MyInt div (MAX_Y + 1);
Y := MyInt mod (MAX_Y + 1);

und falls MIN_Y auch negativ sein kann:
Setzen:MyInt := X * (Max(MAX_Y, Abs(MIN_Y)) + 1) + Y; Auslesen:
Delphi-Quellcode:
X := MyInt div (Max(MAX_Y, Abs(MIN_Y)) + 1);
Y := MyInt mod (Max(MAX_Y, Abs(MIN_Y)) + 1);
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Benutzerbild von divBy0
divBy0

Registriert seit: 4. Mär 2007
Ort: Sponheim
1.020 Beiträge
 
Delphi XE2 Professional
 
#8

Re: Zwei Werte [0..16] in einem Integer festhalten

  Alt 15. Mai 2010, 14:18
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.
Marc
9 von 10 Stimmen in meinem Kopf sagen ich bin nicht verrückt, die 10. summt die Melodie von Tetris... | Wenn das die Lösung ist, dann hätte ich gerne mein Problem zurück! | engbarth.es
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
38.604 Beiträge
 
Delphi 10.4 Sydney
 
#9

Re: Zwei Werte [0..16] in einem Integer festhalten

  Alt 15. Mai 2010, 14:38
@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.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
hathor
(Gast)

n/a Beiträge
 
#10

Re: Zwei Werte [0..16] in einem Integer festhalten

  Alt 15. Mai 2010, 14:52
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;
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 +2. Es ist jetzt 23:42 Uhr.
Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf