私が純粋なCを書いたのは久しぶりなので、ここではC ++です(唯一の違いは出力関数だと思うので、それに従うことができるはずです):
#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;
}
関数'mylog2'は、1から2の間の関連番号を取得するためにいくつかの簡単なログトリックを実行し、その番号でlog2_auxを呼び出します。
log2_auxは、Scorpi0が上記でリンクしたアルゴリズムにほぼ従っています。各ステップで、1ビットの結果が得られます。十分なビットがある場合は、停止します。
コピーを手に入れることができれば、ファインマン物理学の講義、23番は、ログの優れた説明と、多かれ少なかれこの変換を行う方法から始まります。ウィキペディアの記事よりもはるかに優れています。