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 2 von 2     12
Benutzerbild von Lannes
Lannes

Registriert seit: 30. Jan 2005
Ort: Münster
745 Beiträge
 
Delphi 3 Professional
 
#11

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

  Alt 15. Mai 2010, 14:43
Hallo,

da es noch nicht erwähnt wurde, es gibt auch MakeLong() und MakeWord()

Delphi-Quellcode:
var w: Word;
    b1, b2: Byte;
begin
  b1 := 44;
  b2 := 55;
  w := MakeWord(b1, b2);
//auslesen
  b1 := LoByte(w);
  b2 := HiByte(w);
Delphi-Quellcode:
var i: Integer;
    w1, w2: Word;
begin
  w1 := 4444;
  w2 := 5555;
  i := MakeLong(w1, w2);
//auslesen
  w1 := LoWord(i);
  w2 := HiWord(i);
MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
  Mit Zitat antworten Zitat
Benutzerbild von divBy0
divBy0

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

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

  Alt 15. Mai 2010, 15:52
Zitat von himitsu:
@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.
Ja, das stimmt natürlich. Ich hatte dies selbst sogar schon mal genutzt...
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

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

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

  Alt 15. Mai 2010, 16:56
Notfalls hätte ich noch etwas:
Delphi-Quellcode:
Var P: TIntegerPack;

P.Clear;
P.Add(MIN_X, MAX_X, X);
P.Add(MIN_Y, MAX_Y, Y);
i := P.Result;

P.Clear;
P.Add(MIN_X, MAX_X);
P.Add(MIN_Y, MAX_Y);
P.Result := i;
X := P.Value[0];
Y := P.Value[1];
Das Ergebnis dürfte Binär die kleinste Darstellung ergeben.

Delphi-Quellcode:
uses
  SysConst, RTLConsts, SysUtils;

const
  MinInt = Low(Integer);

type
  TIntegerPack = Record
  Private
    FList: Array of Record
              Min, Max: Integer;
              Value: Integer;
            End;
    FResult: UInt64;
    FResSize: UInt64;
    Function GetMin (Index: Integer): Integer;
    Function GetMax (Index: Integer): Integer;
    Function GetVal (Index: Integer): Integer;
    Procedure SetVal (Index, X: Integer);
    Procedure SetResult( X: UInt64);
    Function GetSize (Bits: Integer): Integer;
  Public
    Function Add(Min, Max: Integer; Value: Integer = MinInt): Integer;
    Property Min [Index: Integer]: Integer Read GetMin;
    Property Max [Index: Integer]: Integer Read GetMax;
    Property Value[Index: Integer]: Integer Read GetVal Write SetVal;

    Property Result: UInt64 Read FResult Write SetResult;
    Property ResSize: UInt64 Read FResSize;
    Property Bytes: Integer Index 8 Read GetSize;
    Property Bits: Integer Index 1 Read GetSize;

    Procedure Clear;
  End;

Function TIntegerPack.GetMin(Index: Integer): Integer;
  Begin
    If Cardinal(Index) >= Length(FList) Then
      Raise Exception.CreateResFmt(@SListIndexError, [Index]);
    Result := FList[Index].Min;
  End;

Function TIntegerPack.GetMax(Index: Integer): Integer;
  Begin
    If Cardinal(Index) >= Length(FList) Then
      Raise Exception.CreateResFmt(@SListIndexError, [Index]);
    Result := FList[Index].Max;
  End;

Function TIntegerPack.GetVal(Index: Integer): Integer;
  Begin
    If Cardinal(Index) >= Length(FList) Then
      Raise Exception.CreateResFmt(@SListIndexError, [Index]);
    Result := FList[Index].Value;
  End;

Procedure TIntegerPack.SetVal(Index, X: Integer);
  Begin
    If Cardinal(Index) >= Length(FList) Then
      Raise Exception.CreateResFmt(@SListIndexError, [Index]);
    If (X < FList[Index].Min) or (X > FList[Index].Max) Then
      Raise Exception.CreateRes(@SArgumentOutOfRange);
    FList[Index].Value := X;

    FResult := 0;
    For Index := High(FList) downto 0 do
      With FList[Index] do
        FResult := FResult * Cardinal(Max - Min + 1) + Cardinal(Value - Min);
  End;

Procedure TIntegerPack.SetResult(X: UInt64);
  Var Index: Integer;

  Begin
    For Index := 0 to High(FList) do
      With FList[Index] do Begin
        Value := X mod Cardinal(Max - Min + 1) + Min;
        X := X div Cardinal(Max - Min + 1);
      End;
    //If X <> 0 Then Raise ...;
    FResult := 0;
    For Index := High(FList) downto 0 do
      With FList[Index] do
        FResult := FResult * Cardinal(Max - Min + 1) + Cardinal(Value - Min);
  End;

Function TIntegerPack.GetSize(Bits: Integer): Integer;
  Var X: UInt64;

  Begin
    Result := 0;
    X := FResSize;
    While X <> 0 do Begin
      X := X shr Bits;
      Inc(Result);
    End;
  End;

Function TIntegerPack.Add(Min, Max: Integer; Value: Integer = MinInt): Integer;
  Var Index: Integer;
    X, T: Int64;

  Begin
    Result := Length(FList);
    SetLength(FList, Result + 1);
    Try
      FList[Result].Min := Min;
      FList[Result].Max := Max;

      X := 1;
      For Index := High(FList) downto 0 do
        With FList[Index] do Begin
          T := X;
          X := X * Cardinal(Max - Min + 1);
          If X div Cardinal(Max - Min + 1) <> T Then
            Raise EIntOverflow.CreateRes(@SIntOverflow);
        End;
      FResSize := X;
    Except
      SetLength(FList, High(FList));
      Raise;
    End;
    If Value = MinInt Then Value := Min;
    SetVal(Result, Value);
  End;

Procedure TIntegerPack.Clear;
  Begin
    FList := nil;
    FResult := 0;
    FResSize := 0;
  End;
und noch'n Beispiel:
Delphi-Quellcode:
Uses Dialogs;

Var P: TIntegerPack;

Begin
  P.Add(1, 13);
  P.Add(0, 5);
  P.Add(-2, 3);
  P.Value[0] := 7;
  P.Value[1] := 3;
  P.Value[2] := 1;
  ShowMessage(Format('%d Bytes > %d Bits > $%.*x',
    [P.Bytes, P.Bits, P.Bytes * 2, P.Result]));

  P.Add(1, 13);
  P.Add(0, 5);
  P.Add(-2, 3);
  P.Result := $0117;
  ShowMessage(Format('%d > %d %d %d',
    [P.Result, P.Value[0], P.Value[1], P.Value[2]]));
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
silver-moon-2000

Registriert seit: 18. Feb 2007
Ort: Schweinfurt
170 Beiträge
 
Delphi XE Professional
 
#14

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

  Alt 15. Mai 2010, 21:30
Ich stelle mir gerade die Frage, ob Ihr alle ein wenig zu kompliziert an die Sache rangegangen seid, oder ob ich es mir vielleicht doch zu leicht mache, aber ich verwende das folgende häufiger:

Zahlen zu einer "kombinieren"
kombinierteZahl := (zahl1 shl 16) + zahl2; Zahlen wieder trennen
Delphi-Quellcode:
zahl1neu := (kombinierteZahl and FFFF0000) shr 16;
zahl2neu := kombinierteZahl and 0000FFFF;
Ok, zugegeben, damit ist der Zahlenbereich für zahl1 & zahl2 festgelegt auf 2^(SizeOf(Integer)/2), also Word = 65536, aber das sollte doch reichen, wenn man zwei Zahlen <=16 speichern will

[edit]
ahh, siehste mal guck: MakeLong und MakeWord kannte ich noch nicht, wieder was gelernt
Tobias
Bitte nicht hauen , ich weiß es nicht besser
  Mit Zitat antworten Zitat
Benutzerbild von divBy0
divBy0

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

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

  Alt 15. Mai 2010, 21:53
Hatte ich doch beschrieben, mit High- und Low-Word.
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
silver-moon-2000

Registriert seit: 18. Feb 2007
Ort: Schweinfurt
170 Beiträge
 
Delphi XE Professional
 
#16

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

  Alt 15. Mai 2010, 21:57
Zitat von divBy0:
Hatte ich doch beschrieben, mit High- und Low-Word.
Aargh, sorry, noch ein Posting, das ich überlesen habe.
Scheint so, dass ich bei jedem Lesen des Threads neue Antworten in der Mitte finde, peinlich irgendwie
Tobias
Bitte nicht hauen , ich weiß es nicht besser
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

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

  Alt 16. Mai 2010, 08:27
@silver-moon-2000:
Macht ja nix, der TE kennt jetzt das Innere dieser Funktionen
und du hast ja auch gleich noch was gelernt.

Zitat von Jonelmeier:
... das soll aber variabel bleiben).
...
Gibt es eine mathematische Lösung für das Problem?
Nun kann er sich variabel eine passende Lösung aussuchen
und verschiedene mathematische und bitverschieberische Lösungen wurden auch genannt.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
schöni

Registriert seit: 23. Jan 2005
Ort: Dresden
445 Beiträge
 
Delphi 7 Personal
 
#18

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

  Alt 17. Mai 2010, 08:02
Zitat von Meflin:
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.
Und so isses auch in wissenschaflichen Fachbüchern erklärt. Da weiß ich aber immer noch nich, die größte Zah wovon.

Was also stellt diese magische Zahl i dar?

Und wofür steht q?

f(i) <= 39 kann zB sein: 39, 38, 37,...1, 0

Aber das sollte ja nun zu Rückberechnung der beiden gespeicherten Zahlen passen? Also bitte noch mal genauer erklären, damit ein unbedarfter das Beispeil auch nachvollziehen kann. Probieren, um die passende Zahl zu finden, reicht mir nicht. Im Extremfall probier ich dann alle zwischen 1 und 37 oder allgemein 1..X durch, was nicht gerade laufzeitfreundlich ist.

Oder ist i immer die Summe der beiden Zahlen.

Was wenn die Summe größer wird als dies Summe aus der Formel?
Damit der Topf nicht explodiert, lässt man es ab und zu mal zischen.
  Mit Zitat antworten Zitat
Benutzerbild von Meflin
Meflin

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

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

  Alt 17. Mai 2010, 13:11
Zitat von schöni:
Was also stellt diese magische Zahl i dar?
Im Grunde das, was jeder Programmierer darunter versteht: Eine Schleifenvariable Der offizielle Weg besteht darin, bei 0 beginnend f(i) auszurechnen, solange bis f(i) >= h (wobei h das Ergebnis der Paarungsfunktion ist). Das vorletzte (oder letzte im Fall =) Ergebnis bei Abbruch ist dann das gesuchte i.

Zitat:
Und wofür steht q?
Rein mathematisch gedacht bekommst du aus obigem Test eine Menge von Zahlen zurück, die die Bedingung (<= h) erfüllen. q ist die Funktion, die dir aus dieser Menge die Größte zurückgibt. Nicht mehr, aber auch nicht weniger.

Man kann i und damit die beiden Werte auch direkt berechnen:
i = floor(sqrt(2h) - 1/2)

(Online Formeleditor mit Einbindungsfunktion für Webseiten anybody?)
Leo S.
  Mit Zitat antworten Zitat
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 +1. Es ist jetzt 23:14 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