![]() |
Re: Zwei Werte [0..16] in einem Integer festhalten
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); |
Re: Zwei Werte [0..16] in einem Integer festhalten
Zitat:
|
Re: Zwei Werte [0..16] in einem Integer festhalten
Notfalls hätte ich noch etwas:
Delphi-Quellcode:
Das Ergebnis dürfte Binär die kleinste Darstellung ergeben. :gruebel:
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];
Delphi-Quellcode:
und noch'n Beispiel:
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;
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]])); |
Re: Zwei Werte [0..16] in einem Integer festhalten
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"
Delphi-Quellcode:
Zahlen wieder trennen
kombinierteZahl := (zahl1 shl 16) + zahl2;
Delphi-Quellcode:
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 :stupid:
zahl1neu := (kombinierteZahl and FFFF0000) shr 16;
zahl2neu := kombinierteZahl and 0000FFFF; [edit] ahh, siehste mal guck: MakeLong und MakeWord kannte ich noch nicht, wieder was gelernt |
Re: Zwei Werte [0..16] in einem Integer festhalten
Hatte ich doch beschrieben, mit High- und Low-Word. :-D
|
Re: Zwei Werte [0..16] in einem Integer festhalten
Zitat:
Scheint so, dass ich bei jedem Lesen des Threads neue Antworten in der Mitte finde, peinlich irgendwie :wall: |
Re: Zwei Werte [0..16] in einem Integer festhalten
@silver-moon-2000:
Macht ja nix, der TE kennt jetzt das Innere dieser Funktionen und du hast ja auch gleich noch was gelernt. Zitat:
und verschiedene mathematische und bitverschieberische Lösungen wurden auch genannt. |
Re: Zwei Werte [0..16] in einem Integer festhalten
Zitat:
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? |
Re: Zwei Werte [0..16] in einem Integer festhalten
Zitat:
Zitat:
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?) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:55 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