Index des niedrigsten Bit

7

Ich möchte den schnellsten Weg finden, um den Index des niedrigstwertigen Bits einer langen Länge zu erhalten. zB:

%Vor%

Lösungen mit Looping und Shifting sind zu langsam. zB:

%Vor%

EDIT: Info zur Verwendung

Die Funktion, die fsll verwendet, kann ihre Verwendung nicht wirklich reduzieren, aber hier ist sie (vereinfacht natürlich). Es iteriert nur durch die Indizes und macht etwas mit ihnen. Diese Funktion ist vielleicht die am meisten verwendete Funktion in meiner gesamten Anwendung, trotz einer Menge Caching ihres Wertes. Es ist ein legaler Move-Generator in meiner alpha-beta Suchmaschine.

%Vor%     
dharga 25.09.2009, 15:31
quelle

11 Antworten

11

Intel hat spezielle Anweisungen zum Auffinden von Bits mit der niedrigsten oder höchsten Ordnung. BSF scheint wie, was Sie brauchen. Soweit es in C zu tun hat, hat die Bit Twiddling Hacks Seite , was Sie brauchen.

>

Zumindest könnten Sie eine Tabelle mit Nibbles oder Bytes verwenden, um die Dinge zu beschleunigen. So etwas (demonstriert für int, aber leicht änderbar, wenn nötig).

%Vor%     
Evan Teran 25.09.2009, 15:38
quelle
9

Der schnellste, den ich gefunden habe, ist ffsll (long long) in string.h.

    
dharga 25.09.2009 15:33
quelle
4

Wenn Sie Visual Studio verwenden, _BitScanForward :

Probieren Sie für gcc _BitScanForward oder __builtin_ctz :

aus

Wie immer sollte der generierte Code konsultiert werden, um sicherzustellen, dass die richtigen Anweisungen generiert werden.

    
please delete me 26.09.2009 15:26
quelle
3

Sie können das niedrigste gesetzte Bit mit x & (~x + 1) isolieren; Dadurch erhalten Sie den niedrigsten Bitwert, nicht den Index (z. B. wenn x = 01101000, dann ist das Ergebnis 00001000). Der schnellste Weg, den ich kenne, um von dort zu einem Index zu gelangen, ist wahrscheinlich eine switch-Anweisung:

%Vor%

Hässlich, aber keine Looping beteiligt.

    
John Bode 25.09.2009 16:35
quelle
2

Wie wäre es mit einer Art binärer Suche?

Betrachten Sie die niedrigen Bits, die sich aus einem bitweisen und einem Maskenwert ergeben, die alle Einsen in der unteren Hälfte sind. Wenn dieser Wert Null ist, wissen Sie, dass das kleinste Bit in der oberen Hälfte der Zahl ist.

schneiden Sie die Sache anders halb und gehen Sie wieder.

    
Mikeb 25.09.2009 15:43
quelle
2

Dies könnte für 32 Bits funktionieren. Sollte einfach genug sein, um 64 zu verlängern.

%Vor%

Offensichtlich, wenn es eine Möglichkeit gibt, die Hardware es zu tun, d. h. wenn spezielle CPU-Anweisungen verfügbar sind, ist dies der richtige Weg.

    
JustJeff 26.09.2009 14:37
quelle
0

Wie wäre es mit so etwas? Es reduziert die Anzahl der Schleifen erheblich.

%Vor%     
Tim Allman 25.09.2009 15:53
quelle
0

Ich habe zwei Funktionen geschrieben, sie geben dasselbe Ergebnis zurück wie ffsll ().

%Vor%

Ich weiß nicht, welcher der schnellste ist: ffsll (), func1 () oder func2 ()?

    
sambowry 25.09.2009 23:04
quelle
0

Hier sind zwei Implementierungen, zuerst nach intrinsics / assembly, zweitens nach c / c ++ (Index beginnt bei 0)

%Vor%     
Orup 26.01.2011 22:48
quelle
-1

Um das am meisten gesetzte Bit zu erhalten, kann der folgende Ausdruck verwendet werden:

Betrachte die Variable als X

x & amp; ~ (x - 1) gibt eine Binärzahl, die nur das gesetzte Bit enthält, mit dem Rest alle Nullen

Beispiel

%Vor%

Verschieben Sie nun fortlaufend diese Binärzahl nach rechts, bis die Zahl Null ist, und zählen Sie die Anzahl der Verschiebungen, die die am weitesten rechts gesetzte Bitnummer ergeben.

    
Dungeon Hunter 06.07.2013 06:07
quelle
-3

Sie können die Komplexität Ihres Algorithmus halbieren, indem Sie zuerst prüfen, ob Ihre Zahl ungerade oder gerade ist. Wenn es gerade ist, hast du das niedrigste Bit, das erste Bit.

Für seltsame Fälle können Sie eine solche binäre Suche implementieren ...

    
Lopoc 26.09.2009 00:28
quelle

Tags und Links