Я столкнулся с этим вопросом, когда был на собеседовании при приеме на работу в CS. Я понятия не имею об этом, не говоря уже о реализации кода …
Могу я получить несколько советов?
P.S. exp () - это функция y = e ^ x, а ln () - это y = ln (x)
3 ответа
Вы можете найти значение в журнале времени путем двоичного поиска ответа. Это возможно, потому что log X - монотонно возрастающая функция.
(любезно предоставлено WolframAlpha ) .
Например, если значение, логарифм которого мы должны вычислить (предположим, что это X), больше 1, тогда начните с предположения, что answer = X. Увеличьте степень e ^ answer и проверьте, больше или меньше значение чем X. Теперь в зависимости от того, больше или меньше полученное вами значение X, вы можете уточнить свои пределы. Поиск прекращается, когда вы достигли подходящего диапазона вашего ответа.
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;
}
}
}
Точно так же, если значение X меньше 1, вы можете свести этот случай к уже рассмотренному нами, т.е. когда X больше 1. Например, если X = 0,04, то
Журнал 0,04 = журнал (4/100) = (журнал 4) - (журнал 100)
X>1
и X<1
?
x<1
у нас есть ln(x)>x
- таким образом, если мы начнем поиск со значением меньше, чем x
, мы никогда не закончим (потому что (lo+hi/2)
также будет меньше, чем x
)
X<1
, я думаю, вам следует вместо этого сделать ln(1/X) = -ln(X)
. И помните, что вопрос о ln(X)
, который является натуральным логарифмом, а не основанием 10.
Если X положительный, то логарифм можно найти с помощью метода Ньютона.
X_ {0} = 0
X_ {n + 1} = X_ {n} - (ехр (X_ {n}) - X) / (ехр (X_ {n})
Очень быстрая сходимость.
X_{n+1} = X_{n} + X / exp(X_{n}) - 1
.
X
здесь константа, значение, для которого мы пытаемся найти натуральный логарифм. (Возможно, было бы понятнее, если бы X
переименовали в Y
, а X_i
оставили бы как есть.)
Адаптация этого ответа для масштабирования X в диапазоне [0, e]. Мы знаем кое-что о ln(x)
, ln(x)
определено только для 0 ln(x^a) = a * ln(x)
в частности ln(x^(-1)) = - ln(x)
, ln(X/e) = ln(X)-ln(e)
так 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;
}
}
}
Если вы посмотрите на фактические реализации математических функций в библиотеках. Они выполняют довольно много работы по предварительному масштабированию, чтобы сузить диапазоны входных данных, вероятно, более агрессивно, чем это делается здесь.
Похожие вопросы
Новые вопросы
algorithm
Алгоритм - это последовательность четко определенных шагов, которые определяют абстрактное решение проблемы. Используйте этот тег, если ваша проблема связана с дизайном алгоритма.
exp(y) = x
(и не использовать Тейлора). Ньютон даст вам самую быструю сходимость, но вам нужно проверить, имеет ли значение выбор начального значения.