AGB  ·  Datenschutz  ·  Impressum  







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

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
Benutzerbild von himitsu
himitsu

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

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]]));
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Antwort Antwort


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 13:51 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