I came cross this question when I was in a CS job interview. I have no idea about it, let alone implement the code……
Could I get some tips?
P.S. exp() is the function y = e^x and ln() is y = ln(x)
To use the LN function in Excel, you first need to enter the number you want to calculate the logarithm of into a cell. Next, you need to type "=LN(" into the cell and then click on the cell with the number you want to calculate the logarithm of. After that, press the enter key to calculate the logarithm.
The difference between log and ln is that log is defined for base 10 and ln is denoted for base e. For example, log of base 2 is represented as log2 and log of base e, i.e. loge = ln (natural log).
The ln() function comes with the SciViews package that takes a vector as an argument and returns the natural log of the input vector. We define ln() and ln1p() as wrappers for log()“ with defaultbase = exp(1) argument and for log1p(), respectively.
You can find the value in log time by binary searching the answer. This is possible because log X is a monotonically increasing function.
(courtesy of WolframAlpha).
For example, if the value whose logarithm we have to calculate (assume it to be X) is greater than 1, then start with an assumption of answer = X. Raise the power e^answer and check if the value is greater than or smaller than X. Now based on whether the value you get is greater than or lesser than X, you can refine your limits. The search stops when you have reached within suitable ranges of your answer.
double log(double X){
double lo = 1;
double hi = X;
while(true){
double mid = (lo+hi)/2;
double val = power(e, mid);
if(val > X){
hi = mid;
}
if(val < X){
lo = mid;
}
if(abs(val-X) < error){
return mid;
}
}
}
Similarly, if the value of X is smaller than 1, then you can reduce this case to the case we have already considered, ie. when X is greater than 1. For example if X = 0.04, then
log 0.04 = log (4/100) = (log 4) - (log 100)
If X is positive, then the logarithm can be found using Newton's method.
X_{0} = 0
X_{n+1} = X_{n} - (exp(X_{n}) - X) / (exp(X_{n})
Very fast convergence.
Adapting this answer to get X scaled in the range [0,e]. A few things we know about ln(x)
, ln(x)
is only defined for 0 < x, ln(1)=0
, the results can be any number from -infinity to +infinity. ln(x^a) = a * ln(x)
in particular ln(x^(-1)) = - ln(x)
, ln(X/e) = ln(X)-ln(e)
so ln(X) = ln(X/e) + 1
.
double E = exp(1);
double ln(double X) {
if(X<0) return NaN;
// use recursion to get approx range
if(X<1) {
return - ln( 1 / X );
}
if(X>E) {
return ln(X/E) + 1;
}
// X is now between 1 and e
// Y is between 0 and 1
double lo = 0;
double hi = 1;
while(true){
double mid = (lo+hi)/2;
double val = exp(mid);
if(val > X){
hi = mid;
}
if(val < X){
lo = mid;
}
if(abs(val-X) < error){
return mid;
}
}
}
If you look at the actual implementations of mathematical functions in the libraries. They do quite a lot of prescaling work to narrow the ranges of input, probably more aggressive than is done here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With