Einzelnen Beitrag anzeigen

einbeliebigername

Registriert seit: 24. Aug 2004
140 Beiträge
 
Delphi XE8 Professional
 
#17

AW: Index vom x-tem gesetztem Bit

  Alt 3. Jun 2020, 10:54
Hallo,

ich will auch mitspielen. Habe gleich zwei Varianten. Leider kennt Delphi die Operatoren ROL und ROR nicht. Ich glaube Pascal hatte die.

Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

{$IFOPT Q+}{$DEFINE OVERFLOWCHECKSON}{$ENDIF}
{$Q-}
function Rol(const aValue: Byte; const aN: Integer): Byte; //inline;
begin
  Result:= ((aValue shl (aN and 7)) and $FF) or (aValue shr (8- (aN and 7)));
end;

function Ror(const aValue: Byte; const aN: Integer): Byte; //inline;
begin
  Result:= (aValue shr (aN and 7)) or ((aValue shl (8- (aN and 7))) and $FF);
end;
{$IFDEF OVERFLOWCHECKSON}{$Q+}{$ENDIF}

function ValueOfNthSetBitV1(aValue: Byte; aN: UInt64): Byte;
begin
  if aValue= 0 then
    raise Exception.Create('Fehlermeldung');
  Result:= 0;
  while aN> 0 do
  begin
    if Result= 0 then
      Result:= 1
    else
      Result:= Rol(Result, 1);
    if aValue and 1<> 0 then
      Dec(aN);
    aValue:= Ror(aValue, 1);
  end;
end;

function ValueOfNthSetBitV2(const aValue: UInt64; const aValueBitWidth: Byte; const aN: UInt64): Byte;
var
  vTmp: Array[0..63] of UInt64;
begin
  if aValueBitWidth= 0 then
    raise Exception.Create('Fehlermeldung');
  var vBitCount: Byte := 0;
  for var vI: Integer := 0 to aValueBitWidth- 1 do
  begin
    var vBit: UInt64 := 1 shl vI;
    if (aValue and vBit)<> 0 then
    begin
      vTmp[vBitCount]:= vBit;
      Inc(vBitCount);
    end;
  end;
  if vBitCount= 0 then
    raise Exception.Create('Fehlermeldung');
  Result:= vTmp[(aN- 1) mod vBitCount];
end;

begin
  try
    WriteLn(Format('ValueOfNthSetBitV1(42, 3)= %d', [ValueOfNthSetBitV1(42, 3)]));
    WriteLn(Format('ValueOfNthSetBitV1(42, 5)= %d', [ValueOfNthSetBitV1(42, 5)]));
    WriteLn(Format('ValueOfNthSetBitV2(42, 3)= %d', [ValueOfNthSetBitV2(42, 8, 3)]));
    WriteLn(Format('ValueOfNthSetBitV2(42, 5)= %d', [ValueOfNthSetBitV2(42, 8, 5)]));
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
Mit freundlichen Grüßen, einbeliebigername.
  Mit Zitat antworten Zitat