Как написать логарифмическую функцию 10 на С++?

Я знаю, что это может показаться повторяющимся вопросом, но я не смог найти ответ на предыдущие вопросы. Я имею в виду, как написать функцию журнала с основанием 10 с помощью простых циклов и не использовать встроенную функцию журнала в С++.


person hamed    schedule 01.01.2017    source источник
comment
Путем вычисления log2 и использования логарифмического изменения базовой формулы с сохраненной константой   -  person StoryTeller - Unslander Monica    schedule 01.01.2017
comment
И log2, и log10 - это мой вопрос. Как написать эту функцию с самого начала?   -  person hamed    schedule 01.01.2017
comment
Вы вообще не представляете, как начать? Это очень общий вопрос, и простое написание функции для вас не очень полезно.   -  person Dave Costa    schedule 01.01.2017
comment
Я написал свой код, но он правильно работает для таких чисел, как 10, 100, 1000 и так далее. Я хочу, чтобы код работал правильно для каждого числа.   -  person hamed    schedule 01.01.2017
comment
целочисленный журнал или журнал с плавающей запятой? в любом случае есть тонны дубликатов. см. graphics.stanford.edu/~seander/bithacks.html#IntegerLog10   -  person phuclv    schedule 01.01.2017
comment
Вы должны изучить, как логарифмическая функция может быть аппроксимирована степенным рядом или другими итерационными методами. Эти знания больше связаны с математикой, чем с программированием. Начните читать здесь.   -  person n. 1.8e9-where's-my-share m.    schedule 01.01.2017
comment
Вычисления логарифмов без math.h   -  person phuclv    schedule 01.01.2017
comment
Просто используйте встроенную функцию журнала. Это будет быстрее, чем любой цикл, который вы напишете.   -  person Raymond Chen    schedule 01.01.2017


Ответы (3)


Самый простой способ — вычислить натуральный логарифм (ln) с помощью ряда Тейлора. Как только вы нашли натуральный логарифм, просто разделите его на ln(10), и вы получите логарифм по основанию 10.

Ряд Тейлора довольно просто реализовать на C. Если z — это число, для которого вы ищете журнал, вам просто нужно выполнить несколько итераций, каждый раз умножая аккумулятор на (z-1). В пределе, чем больше итераций вы выполните, тем точнее будет ваш результат. Несколько раз сверяйтесь с версией libC log10(), пока не будете довольны точностью.

Это «числовой подход». Существуют и другие числовые решения для нахождения логарифма числа, которые могут дать более точные результаты. Некоторые из них можно найти по той ссылке в Википедии, которую я вам дал.

person giusti    schedule 01.01.2017

Предполагая, что под «логарифмической базой 10» вы подразумеваете «количество раз, когда n можно разделить на 10, прежде чем получится значение ‹ 10»:

log = 0;
// Assume n has initial value N
while ( n >= 10 ) {
    // Invariant: N = n * 10^log
    n /= 10;
    log += 1;
}
person Scott Hunter    schedule 01.01.2017
comment
Эта функция работает правильно, если ввести, например, 75? - person hamed; 01.01.2017
comment
Если предположение верно (то есть вам нужна только целая часть), то да: это приведет к log=1. - person Scott Hunter; 01.01.2017
comment
Я хочу, чтобы он возвращал реальный log10 числа. Я имею в виду то, что мы считаем с помощью простого калькулятора. - person hamed; 01.01.2017

Вы получите более быструю сходимость с помощью метода Ньютона. Используйте что-то вроде этого (написанное вручную, не скомпилированное или протестированное, использует f(r) = 2**r - x для вычисления log2(x) ):

double next(double r, double x) {
    static double one_over_ln2 = 1.4426950408889634;
    return r - one_over_ln2 * (1 - x / (1 << static_cast<int>(r)));

double log2(double x) {
    static double epsilon = 0.000000001; // change this to change accuracy
    double r = x / 2;. // better first guesses converge faster
    double r2 = next(r, x);
    double delta = r - r2;
    while (delta * delta > epsilon) { 
        r = r2;
        r2 = next(r, x);
        delta = r - r2
    }
    return r2;
}

double log10(double x) {
    static double log2_10 = log2(10);
    return log2(x) / log2_10;
}
person Paul Evans    schedule 01.01.2017