Einzelnen Beitrag anzeigen

Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#34

AW: Bit-Schiebereien

  Alt 12. Mai 2014, 09:59
Sodele, ich habe die Methode nochmals überarbeitet und jetzt kann man auch die vollen 32bit für einen Integer auslesen, ohne dass es einem um die Ohren fliegt

Im Debug-Mode bleibt es bei ca. 16ms und im Release-Mode sind es ca. 7ms (jeweils für 1.000.000 Abfragen). Ich denke mal, das müsste von der Geschwindigkeit ausreichen

Delphi-Quellcode:
unit BaseData;

interface

uses
  System.SysUtils;

type
  TBaseData = class
  private
    FData : TBytes;
  protected
    function GetData( const Index : integer ) : integer;
  public
    constructor Create( AData : TBytes );
  end;

implementation

{ TBaseData }

constructor TBaseData.Create( AData : TBytes );
begin
  inherited Create;
  FData := AData;
end;

function TBaseData.GetData( const Index : integer ) : integer;
var
  LBitCount : integer;
  LBitOffset : integer;
  LByteOffset : integer;
  LByteIdx : PByte;
  LMask : Byte;
begin
  LBitCount := index and $FF;

  if LBitCount > 32
  then
    raise EArgumentOutOfRangeException.CreateFmt( 'Index %x contains invalid BitWidth %x', [index, LBitCount] );

  LBitOffset := ( index shr 8 ) and $FFFFFF;
  LByteOffset := LBitOffset div 8;
  LBitOffset := LBitOffset - LByteOffset * 8;
  LByteIdx := @FData[LByteOffset];

  { TODO : RangeCheck for LByteOffset }

  if LBitCount > 0
  then
    begin
      LMask := ( 1 shl ( 8 - LBitOffset ) ) - 1;
      Result := ( LByteIdx^ and LMask );
      LBitCount := LBitCount - ( 8 - LBitOffset );
    end
  else
    begin
      Result := 0;
      Exit;
    end;

  while LBitCount >= 8 do
    begin
      Inc( LByteIdx );
      Result := Result shl 8;
      Result := Result or LByteIdx^;
      LBitCount := LBitCount - 8;
    end;

  if LBitCount > 0
  then
    begin
      Inc( LByteIdx );
      Result := Result shl LBitCount;
      LMask := ( 1 shl ( 8 - LBitOffset ) ) - 1;

      Result := Result or ( ( LByteIdx^ shr ( 8 - LBitCount ) ) and LMask );
    end;

end;

end.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (12. Mai 2014 um 10:02 Uhr)
  Mit Zitat antworten Zitat