Es ist lange her, dass ich reines C geschrieben habe, also hier ist es in C++ (ich denke, der einzige Unterschied ist die Ausgabefunktion, also sollten Sie in der Lage sein, ihr zu folgen):
#include <iostream>
using namespace std;
const static double CUTOFF = 1e-10;
double log2_aux(double x, double power, double twoToTheMinusN, unsigned int accumulator) {
if (twoToTheMinusN < CUTOFF)
return accumulator * twoToTheMinusN * 2;
else {
int thisBit;
if (x > power) {
thisBit = 1;
x /= power;
}
else
thisBit = 0;
accumulator = (accumulator << 1) + thisBit;
return log2_aux(x, sqrt(power), twoToTheMinusN / 2.0, accumulator);
}
}
double mylog2(double x) {
if (x < 1)
return -mylog2(1.0/x);
else if (x == 1)
return 0;
else if (x > 2.0)
return mylog2(x / 2.0) + 1;
else
return log2_aux(x, 2.0, 1.0, 0);
}
int main() {
cout << "5 " << mylog2(5) << "\n";
cout << "1.25 " << mylog2(1.25) << "\n";
return 0;
}
Die Funktion "mylog2" führt einige einfache Log-Tricks aus, um eine Zahl zwischen 1 und 2 zu erhalten, und ruft dann log2_aux mit dieser Zahl auf.
Der log2_aux folgt mehr oder weniger dem Algorithmus, den Scorpi0 oben verlinkt hat. Bei jedem Schritt erhält man 1 Bit des Ergebnisses. Wenn Sie genug Bits haben, stoppen Sie.
Wenn Sie ein Exemplar der Feynman Lectures on Physics, Nummer 23, ergattern können, finden Sie zu Beginn eine großartige Erklärung der Logs und mehr oder weniger, wie man diese Umwandlung vornimmt. Weitaus besser als der Wikipedia-Artikel.