Какова сложность логарифмической функции?

Какова сложность функции логарифма по основанию 10?


person Paul Manta    schedule 06.09.2011    source источник
comment
Разве это не зависит от используемого алгоритма? Таблица поиска, например, O (1).   -  person Thilo    schedule 06.09.2011


Ответы (2)


Это действительно зависит от области значений, для которых вы хотите вычислить логарифм.

Для дублей IEEE многие процессоры могут логарифмировать в одной ассемблерной инструкции; Например, в x86 есть инструкции FYL2X и FYL2XP1. Хотя обычно подобные инструкции принимают логарифмы только по некоторому фиксированному основанию, их можно использовать для логарифмирования по произвольным основаниям, используя тот факт, что

loga b = logc b / logc a

просто взяв два логарифма и найдя их частное.

Для общих целых чисел (произвольной точности) вы можете использовать повторное возведение в квадрат в сочетании с двоичным поиском для логарифмирования, используя только O(log log n) арифметических операций (каждый раз, когда вы возводите число в квадрат, вы удваиваете показатель степени, что означает, что вы можете возводить в квадрат только число log log n раз, прежде чем вы превысите его значение и сможете выполнить двоичный поиск). Используя некоторые милые трюки с числами Фибоначчи, вы можете сделать это всего за O( log н) пробел. Если вы вычисляете двоичный логарифм, есть несколько забавных трюков, которые вы можете использовать с битовыми сдвиги для вычисления значения за меньшее время (хотя асимптотическая сложность такая же).

Для произвольных действительных чисел логика сложнее. Вы можете использовать метод Ньютона или ряд Тейлора для вычисления логарифмов с определенной точностью, хотя, признаюсь, я не знаком с методами для этого. Однако на самом деле вам редко нужно это делать, потому что большинство действительных чисел являются двойниками IEEE, и в этом случае есть лучшие алгоритмы (или даже аппаратные инструкции).

Надеюсь это поможет!

person templatetypedef    schedule 06.09.2011
comment
Для целых чисел часто также есть инструкция (или короткая последовательность, чтобы сделать CTZ(x & (x - 1)) или wordsize - LZC(x)) - но AFAIK, которая вообще не помогает с временной сложностью (только фактическая скорость) - person harold; 06.09.2011
comment
@templatetypedef Который вы можете умножить на постоянный коэффициент, чтобы получить логарифмы в любом другом основании, как вы только что продемонстрировали. :) - person Nick Johnson; 07.09.2011
comment
@NickJohnson Да, и хотя это действительно быстро, мы должны отметить, что сама операция умножения имеет более высокую логарифмическую сложность: en.wikipedia.org/wiki/ - person Rustam A.; 25.04.2021

Чтобы сделать log(n) в O(1) (где n — целое число)

int log(long long x)
{
    return 64 - __builtin_clzl(x) - 1;
}

__builtin_clzl(x) см. здесь

person iamakshatjain    schedule 15.05.2020
comment
Это вычислит двоичный логарифм числа, предполагая, что число является целым числом. Но если вы хотите вычислить логарифмическую базу 10, я думаю, вам нужно использовать другую стратегию. - person templatetypedef; 16.05.2020