Из любопытства я попытался воспроизвести:
#include <stdio.h>
int msb(unsigned int v) {
unsigned int r = 0;
while (v >>= 1) r++;
return r;
}
float ln(float y)
{
int log2;
float divisor, x, result;
log2 = msb((int)y); // See: https://stackoverflow.com/a/4970859/6630230
printf("log2: %d\n", log2);
divisor = (float)(1 << log2);
printf("divisor: %f\n", divisor);
x = y / divisor; // normalized value between [1.0, 2.0]
printf("x: %f\n", x);
result = -1.7417939 + (2.8212026 + (-1.4699568 + (0.44717955 - 0.056570851 * x) * x) * x) * x;
result += ((float)log2) * 0.69314718; // ln(2) = 0.69314718
return result;
}
int main()
{
printf("ln(12510): %f\n", ln(12510));
}
Вывод:
log2: 13
divisor: 8192.000000
x: 1.527100
ln(12510): 9.434252
Live Demo on coliru
Я только что попробовал это в своем карманном калькуляторе Windows 7 и получил:
9.434283603460956823997266847405
Первые 5 цифр идентичны. - Остальное я бы рассматривал как вопросы округления, не зная, какой из них стал ближе.
Однако в вопросе есть опечатка (или ошибка):
y = 12510 (0x30DE), log2 = 13, делитель = 26, x = 481,1538
divisor = (float)(1 << log2);
с log2 = 13
выходами 8192
.
log2 << 1
приведет к 26
.
Ради интереса я изменил строку на divisor = (float)(log2 << 1);
и получил следующий вывод:
log2: 13
divisor: 26.000000
x: 481.153839
ln(12510): -2982522368.000000
Итак, это меня немного озадачило:
Представленный код кажется правильным, но OP, по-видимому, неправильно его интерпретировал (или напоминал).