AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Index vom x-tem gesetztem Bit

Ein Thema von calibra301 · begonnen am 1. Jun 2020 · letzter Beitrag vom 16. Jun 2020
Antwort Antwort
Seite 2 von 3     12 3   
TBx
(Moderator)

Registriert seit: 13. Jul 2005
Ort: Stadthagen
1.790 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#11

AW: Index vom x-tem gesetztem Bit

  Alt 2. Jun 2020, 19:55
Magst Du uns einmal darüber aufklären, wofür Du diese Funktion brauchst?
Mir fällt da so spontan kein Anwendungsfall für ein.
Gruß Thomas
- Moderator Delphi-Praxis -
- Admin Delphi-Treff
- Embarcadero MVP
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
8.451 Beiträge
 
Delphi 10.4 Sydney
 
#12

AW: Index vom x-tem gesetztem Bit

  Alt 3. Jun 2020, 09:16
Probier mal mask := Bitmask(0,5,false);
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Maekkelrajter

Registriert seit: 8. Mär 2017
Ort: Köln
88 Beiträge
 
Delphi 10.4 Sydney
 
#13

AW: Index vom x-tem gesetztem Bit

  Alt 3. Jun 2020, 11:01
Beispiel: 42 = Binär 00101010, suche das fünfte gesetzte Bit von rechts.
Sind ja nur 3 Bit gesetzt also vorne wieder anfangen.
Ergebnis wäre dann 8
Ah jetzt ja! Jetzt habe ich wohl endlich verstanden, was du meinst mit: suche das fünfte gesetzte Bit von rechts
Dann kann man die Funktion aber auch deutlich vereinfachen: Der Unfug mit dem 'Richtungswechsel' kann entfallen und es können 32-Bit Parameter und Variablen verwendet werden.
Und Uwe Raabes Hinweis ist auch berücksichtigt.
Delphi-Quellcode:
Function Bitmask(Value,Position: cardinal):cardinal;
var i,len: Integer;
     mask, Bitcounter: Cardinal;
begin
  result:= 0;
  If value <> 0 Then
  begin
    Bitcounter:= 0;
    len:= (sizeof(value) * 8); // Anzahl der Bits
    while Bitcounter <> Position do
    begin
      for i:= 0 to len - 1 do
      begin
        mask:= (1 shl i);
        If value and mask <> 0 Then inc(Bitcounter);
        if Bitcounter = Position then
        begin
          result:= Mask;
          break;
        end;
      end;
    end;
  end;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  mask: Byte;
begin
  mask := Bitmask(42,5);
  Showmessage('Das '+inttostr(5)+'. Bit ist an Stelle ' + inttostr(mask));
end;
Auch ich grüble allerdings schon die ganze Zeit über die Frage, wozu das Ganze gut sein soll??

Gruß LP
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
8.451 Beiträge
 
Delphi 10.4 Sydney
 
#14

AW: Index vom x-tem gesetztem Bit

  Alt 3. Jun 2020, 11:16
Ich will auch mal:
Delphi-Quellcode:
Function Bitmask(Value, Position: Cardinal): Cardinal;
var
  i: Integer;
  Bitcounter: Cardinal;
  valSet: TIntegerSet;
begin
  result := 0;
  valSet := TIntegerSet(Value);
  If valSet <> [] Then
  begin
    Bitcounter := 0;
    while Bitcounter < Position do
    begin
      for i in valSet do
      begin
        inc(Bitcounter);
        if Bitcounter = Position then
          Exit(1 shl i);
      end;
    end;
  end;
end;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
8.451 Beiträge
 
Delphi 10.4 Sydney
 
#15

AW: Index vom x-tem gesetztem Bit

  Alt 3. Jun 2020, 11:26
Und hier noch eine etwas veränderte Version für Delphi 10.4:
Delphi-Quellcode:
Function Bitmask(Value, Position: Cardinal): Cardinal;
var
  i: Integer;
  Bitcounter: Cardinal;
  cntOfBitsSet: Integer;
  valSet: TIntegerSet;
begin
  result := 0;
  cntOfBitsSet := CountPopulation32(value);
  If (cntOfBitsSet > 0) and (Position > 0) Then
  begin
    if cntOfBitsSet < Position then
      Position := ((Position - 1) mod cntOfBitsSet) + 1;
    valSet := TIntegerSet(Value);
    Bitcounter := Position;
    for i in valSet do
    begin
      dec(Bitcounter);
      if Bitcounter = 0 then
        Exit(1 shl i);
    end;
  end;
end;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Maekkelrajter

Registriert seit: 8. Mär 2017
Ort: Köln
88 Beiträge
 
Delphi 10.4 Sydney
 
#16

AW: Index vom x-tem gesetztem Bit

  Alt 3. Jun 2020, 11:30
Chapeau!
So sieht der Unterschied zwischen einem 'Master Developer' und einem dilettierenden Autodidakten aus!

Erst vor ein paar Jahren, als wieder kostenlose Delphi-Versionen verfügbar waren, hatte ich den Schritt von Delphi 4 zu Delphi 10 gewagt. Alle die schönen Features der modernen Delphi-Versionen, die die Arbeit erleichtern und effizienteren, kompakteren oder auch eleganteren Programmcode ermöglichen, finde ich leider meistens nur per Zufall oder eben durch Beispiele (s. o.)

Gruß LP

Geändert von Maekkelrajter ( 3. Jun 2020 um 12:20 Uhr) Grund: Ergänzung
  Mit Zitat antworten Zitat
einbeliebigername

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

AW: Index vom x-tem gesetztem Bit

  Alt 3. Jun 2020, 11: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
samso

Registriert seit: 29. Mär 2009
430 Beiträge
 
#18

AW: Index vom x-tem gesetztem Bit

  Alt 3. Jun 2020, 12:36
Sehr schöne Vorschläge . Bevor jetzt gleich die Lösung via Cloud-Computing kommt - back to the roots:

Delphi-Quellcode:
program Project5;

uses
  SysUtils;

function CheckBitAsm(const Value, BitNumber: Integer): Integer;
asm
  or Value,Value
  jz @exit
  cmp BitNumber,0
  jle @exit
  mov ecx,1
@loop:
  test Value, ecx
  jz @next
  dec BitNumber
  jz @ready
@next:
  rol ecx,1
  jmp @loop
@ready:
  mov eax, ecx
  ret
@exit:
  xor eax,eax
  ret
end;

begin
  try
// Test
    if CheckBitAsm(42, 3) = 32 then
      writeln('Test 3 - ok');
    if CheckBitAsm(42, 5) = 8 then
      writeln('Test 4 - ok');
    readln;
  except
    on E: Exception do
      writeln(E.ClassName, ': ', E.Message);
  end;
Natürlich nicht ernst gemeint!

Geändert von samso ( 3. Jun 2020 um 12:41 Uhr) Grund: BitNumber soll größer 0 sein
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
8.451 Beiträge
 
Delphi 10.4 Sydney
 
#19

AW: Index vom x-tem gesetztem Bit

  Alt 3. Jun 2020, 12:42
Natürlich nicht ernst gemeint!
Glück gehabt. Ich hätte sonst nämlich gleich nach den Lösungen für Win64, MacOS, Android, iOS und Linux mit ihren jeweiligen Derivaten gefragt
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Andreas13

Registriert seit: 14. Okt 2006
Ort: Nürnberg
419 Beiträge
 
Delphi 10.3 Rio
 
#20

AW: Index vom x-tem gesetztem Bit

  Alt 3. Jun 2020, 12:44
Delphi-Quellcode:
  

  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
Sorry, aber Deine Lösung läßt sich (unter XE5) (noch?) nicht kompilieren. Sind die Variablen-Deklarationen innerhalb der For-Schleife unter XE8 schon zulässig oder sind die Zeilen nur beim Hineinkopieren verrutscht?
Danke & Gruß, Andreas
Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher.
John C. Cornelius

Geändert von Andreas13 ( 3. Jun 2020 um 12:46 Uhr)
  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 +2. Es ist jetzt 19:31 Uhr.
Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf