Spróbowałem sobie zaprogramować liczenie logarytmu naturalnego bez użycia sprzętowych funkcji do ich liczenia i mam dość duże błędy. Liczę z rozwinięcia w szereg i o ile wokół jedynki mam dość dobre wyniki to dla liczb trochę odbiegających od jedynki dokładność mocno spada. Robię coś źle, czy może liczenie logarytmu naturalnego w ten sposób jest z góry skazane na porażkę?
import java.math.BigInteger;
import static java.math.BigInteger.ONE;
import static java.math.BigInteger.ZERO;
import static java.math.BigInteger.valueOf;
public class Main {
public static void main(String[] args) {
int scale = 50;
for (long x = 1l; x < 2l << scale; x += 1l << scale - 7) {
System.out.printf("%f %f %f\n",
x / (double) (1l << scale),
Math.log(x / (double) (1l << scale)),
ln(x, scale) / (double) (1l << scale));
}
}
public static long ln(long x, int scale) {
BigInteger r = ZERO;
BigInteger f = ONE.shiftLeft(scale).subtract(valueOf(x));
BigInteger c = ONE.negate().shiftLeft(scale);
int maxk = 99;
for (int k = 1; k <= maxk; k++) {
c = c.multiply(f);
r = r.multiply(valueOf(k)).shiftLeft(scale).add(c);
}
for (int k = 1; k <= maxk; k++) {
r = r.divide(valueOf(k));
}
r = r.shiftRight(maxk * scale);
return r.longValue();
}
}