Ganzzahlige Logarithmusbasis 2 in O (1)

Es ist oft notwendig, den gesamten Teil der Logarithmusbasis 2 einer ganzen Zahl zu berechnen.



Die direkte Entscheidung besteht darin, eine Schleife zu erstellen und in dieser Schleife die Zahl stÀndig durch zwei zu teilen, bis sie Null wird. Wie viele solcher Unterteilungen aufgetreten sind, ist der Wert des Logarithmus. Ja, diese Methode funktioniert und hat das Recht auf Leben, aber ich möchte zeigen, wie dies ohne Zyklen und komplexe Strukturen möglich ist.



Wir wollen also die folgende Formel berechnen:

y=[lÖG2(x)]],x- -celÜbere,P.ÜberlÜberfundtelbnÜbere





Entscheidung



FĂŒr diejenigen, die nicht an der Argumentation interessiert sind, werde ich sofort vorgefertigte Funktionen zur Berechnung des Logarithmus geben:



uint32_t getHighBit_32(uint32_t x)
{
    x |= x >> 1;
    x |= x >> 2;
    x |= x >> 4;
    x |= x >> 8;
    x |= x >> 16;
    return x - (x >> 1);
}

uint32_t getBitCount_32(uint32_t x)
{
	x = (x & 0x55555555) + ((x >> 1) & 0x55555555);
	x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
	x = (x & 0x0F0F0F0F) + ((x >> 4) & 0x0F0F0F0F);
	x = (x & 0x00FF00FF) + ((x >> 8) & 0x00FF00FF);
	return (x & 0x0000FFFF) + (x >> 16);
}

uint32_t getLog2_32(uint32_t x)
{
    return getBitCount_32(getHighBit_32(x) - 1);
}


ErklÀrungen



Lassen Sie uns zunÀchst die Zahl x in eine binÀre Notation einer bestimmten LÀnge konvertieren.



Zum Beispiel LĂ€nge = 8, aber das ist nicht wichtig und die LĂ€nge der Zahl kann beliebig sein.



Denken Sie nun daran, worauf die Übersetzung einer Zahl in eine binĂ€re Notation basiert. Darstellung der Zahl als Summe von Zweierpotenzen. Die Gradzahl bestimmt die Position des Bits, nĂ€mlich 1. Zum Beispiel:45=32+8+4+1=2fĂŒnf+23+22+20... Jene. Potenznummern 5, 3, 2 und 0. Dies bedeutet, dass das 5., 3., 2., 0. Bit gleich 1 ist. Der Rest der Bits zwischen ihnen ist gleich Null. Bits beginnen auf der rechten Seite. Es stellte sich heraus, dass45zehn=1011012



Es kann angemerkt werden, dass die Übersetzung in die binĂ€re Notation eng mit der Potenzierung zusammenhĂ€ngt und der Logarithmus die Umkehrung der Potenzierung ist und gleich dem Exponenten ist.

2y=x,y=lÖG2(x)



DarĂŒber hinaus ist der Exponent, auf den Sie 2 erhöhen mĂŒssen, die Nummer eines einzelnen Bits in einer binĂ€ren Notation. Es stellt sich heraus, dass, wenn Sie die Nummer eines einzelnen Bits finden, wir den ganzzahligen Teil des Wertes des Logarithmus auf Basis zwei erhalten. Wenn beispielsweise 32 = 100000 ist, befindet sich das eine Bit an fĂŒnfter Stelle, sodass der Logarithmus 5 ist.



Da es jedoch mehrere geben kann, nicht 1, stellt sich die Frage, welches Bit zum Finden des Logarithmus benötigt wird. Die Antwort ist die Nummer des letzten Bits, beginnend auf der rechten Seite der Zahlenaufzeichnung, da die höchste Zweierpotenz den gesamten Teil des Logarithmus bestimmt, der Rest den Bruchteil des Logarithmus ausmacht.



Betrachten Sie ein anderes Beispiel - eine Zahl45zehn=1011012... Das letzte Bit steht an fĂŒnfter Stelle, daher ist der ganzzahlige Teil des Logarithmus von 45 5. und tatsĂ€chlichlÖG2(45)=5.4919... Wir verwerfen den Bruchteil und lassen 5.



Es funktioniert auch mit anderen Zahlen.



Als Ergebnis haben wir festgestellt, dass der ganzzahlige Teil des Logarithmus gleich der Nummer des letzten Bits ist und von rechts zÀhlt. Frage: Wie finde ich die Nummer des letzten Bits?



DafĂŒr gibt es Funktionen, die auf bitweisen Operationen basieren, die ich in dem Buch von G. Warren "Algorithmische Tricks fĂŒr Programmierer" gefunden habe.



  • Abrunden auf eine Zweierpotenz (oder Hervorheben des letzten Bits in der binĂ€ren Notation einer Zahl). Sie können zwar aufrunden, aber dann wird auch der Wert des Logarithmus aufgerundet.
  • ZĂ€hlen der Anzahl einzelner Bits in der binĂ€ren Notation einer Zahl


Beide Funktionen sind dort gut beschrieben, und ich habe ihren Code frĂŒher angegeben.



Unter Verwendung dieser beiden Funktionen lautet der Algorithmus zum Berechnen des Algorithmus wie folgt:



  1. WĂ€hlen Sie das letzte Bit in der Nummer. Jetzt wurde die Nummer als 100000 geschrieben
  2. Subtrahieren Sie eins von der resultierenden Zahl. Dann lautet die Nummer wie folgt: 011111
  3. ZĂ€hlen Sie die Anzahl der Einheitsbits und dies ist der ganzzahlige Wert des Logarithmus


Außergewöhnliche Situation



Der Logarithmus hat eine Ausnahmesituation, wenn x = 0. Theoretisch existiert ein solcher Algorithmus nicht (oder in der Grenze ist er gleich -∞). Da wir jedoch beim Programmieren ein wenig von den Gesetzen der Mathematik abweichen, funktionieren die Funktionen auch dann noch, wenn die Eingabe der Funktion Null ist. In diesem Fall betrĂ€gt der Wert des Logarithmus 32 (wenn die Zahl 32-Bit ist). Dies geschieht, weil die Funktion des Rundens auf die nĂ€chste Zweierpotenz 0 ergibt, dann subtrahieren wir eins von Null und erhalten die Zahl 0xFFFFFFFF, und diese Zahl enthĂ€lt 32 Einheiten, sodass der Logarithmus 32 betrĂ€gt.



Ja, aus mathematischer Sicht ist dies falsch, aber es gibt FĂ€lle. wenn es aus programmtechnischer Sicht nĂŒtzlich ist.



ZÀhlen der LÀnge eines BinÀrcodes



Es ist unwahrscheinlich, dass eine solche Funktion zur Berechnung des mathematischen Logarithmus verwendet wird, da Logarithmen hÀufiger aus reellen Zahlen und nicht aus ganzen Zahlen betrachtet werden.

Die Berechnung der LÀnge eines BinÀrcodes ist in der Praxis jedoch eine hÀufigere Aufgabe.



Es sei ein BinÀrcode einer bestimmten LÀnge gegeben. Dies kann beispielsweise ein Pfad in einem BinÀrbaum sein. Wenn ein einzelnes Bit vor diesen Code geschrieben wird, können Sie die LÀnge dieses Codes ohne Verwendung von Hilfsvariablen berechnen, indem Sie einen ganzzahligen Logarithmus verwenden.



Lassen Sie zum Beispiel den Code 0001110110 angeben. Er wird beispielsweise in eine Zelle mit 32 Bit geschrieben, und wir mĂŒssen hĂ€ufig die LĂ€nge dieses Codes lesen. FĂŒgen Sie dazu vor dem Code ein zusĂ€tzliches Bit hinzu.



Wir erhalten: 10001110110. Und jetzt können wir die LĂ€nge dieses Codes sicher ĂŒber den ganzzahligen Logarithmus berechnen, ohne die LĂ€nge dieses Codes separat an einer anderen Stelle zu speichern.



Wenn wir die LĂ€nge des Codes berĂŒcksichtigen, in der alle Nullen sind, gibt die Funktion die LĂ€nge = 32 zurĂŒck, was möglicherweise falsch ist. Daher muss diese Situation vorausgesehen werden. In einigen Situationen ist es nĂŒtzlich, dass die Funktion 32 zurĂŒckgibt, in anderen beispielsweise Null.



Quellen



  1. G. Warren Algorithmische Tricks fĂŒr Programmierer. Überarbeitete Ausgabe. ", 2004



All Articles