Как возводится возведение в Python?

Я могу вычислить любое нормально вычислимое число финнако (если результат не станет большим) за постоянное время, используя формулу Бине, т.е. формулу замкнутого решения, чтобы вычислить число финнаци. Вот мой код:

для нерекурсивной реализации fibonnaci:

gr = (1 + 5**0.5) / 2
def gfib(n):
    return int(((gr**n - (1-gr)**n) / 5**0.5))

Я понимаю, что a ^ n указывает на экспоненциальную сложность времени выполнения, однако это не тот случай, когда код выполняется в python, так как это мгновенно вычисляет n-й номер финнаси. Я провел некоторое исследование того, как экспоненты реализованы в python (возможно, возведение в степень путем квадратизации?), Чтобы дать постоянное временное решение, которое я получаю, но не нашел окончательного ответа. Любые идеи?

Ответ 1

float.__ pow __() использует C libm, который в полной мере использует аппаратную поддержку для двоичной арифметики с плавающей запятой. Последний представляет числа с использованием логарифмов. Логарифмическое представление позволяет реализовать экспоненту только одно умножение.

Резюме: Экспоненция Float реализована в аппаратном обеспечении и работает с почти постоянной скоростью из-за магии логарифмов.

Ответ 2

Экспоненты для целых чисел могут быть рассчитаны гораздо эффективнее, чем вы думаете. Здесь Википедия должна сказать об этом:

Простейший метод вычисления bⁿ требует операций умножения n-1, но его можно вычислить более эффективно, чем это показано на следующем примере. Для вычисления 2¹⁰⁰ обратите внимание, что 100 = 64 + 32 + 4. Вычислите следующее в следующем порядке:

2² = 4
(2²)² = 2⁴ = 16
(2⁴)² = 2⁸ = 256
(2⁸)² = 2¹⁶ = 65,536
(2¹⁶)² = 2³² = 4,294,967,296
(2³²)² = 2⁶⁴ = 18,446,744,073,709,551,616
2⁶⁴ × 2³² × 2⁴ = 2¹⁰⁰ = 1,267,650,600,228,229,401,496,703,205,376

Для этой серии шагов требуется только 8 операций умножения вместо 99 (так как последний продукт выше принимает 2 умножения).

В общем случае количество операций умножения, необходимых для вычисления bⁿ, можно свести к Θ (log n) с помощью возведения в степень возведения в квадрат или (в более общем плане) усиление последовательности цепочек. Поиск минимальной последовательности умножений (цепочка сложения минимальной длины для экспоненты) для bⁿ является трудной задачей, для которой в настоящее время не известны эффективные алгоритмы (см. Проблему суммы подмножества), но доступно много разумно эффективных эвристических алгоритмов [29].

Страница экспонентации по квадрату трудно подвести, но в основном идея о том, что 2⁸ == (2⁴) ² == (2²) ²) ², поэтому вместо вычисления 2 × 2 × 2 × 2 × 2 × 2 × 2 × 2 = 256 вы можете рассчитать 2 × 2 = 4; 4 × 4 = 16; 16 × 16 = 256.