好久没写纯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 期,从对日志的精彩解释开始,以及或多或少地如何进行这种转换。大大优于维基百科的文章。