Конечно, числа Фибоначчи могут быть вычислены в O (n), применяя формулу Бине:
from math import floor, sqrt
def fib(n):
return int(floor(((1+sqrt(5))**n-(1-sqrt(5))**n)/(2**n*sqrt(5))+0.5))
Как отмечают комментаторы, это не O (1), а O (n) из-за 2**n
. Также разница в том, что вы получаете только одно значение, а при рекурсии вы получаете все значения Fibonacci(n)
до этого значения.
Из спецификации (раздел 7.20.3)
Его значение, определяемое реализацией, должно быть равным или больше по величине (абсолютное значение) чем соответствующее значение, указанное ниже
blockquote>[Emphasis mine]
Таким образом, упомянутые значения являются только минимальными значениями. Реализация может иметь большие ограничения. Я ожидал бы, что
ptrdiff_t
будет длиной слова целевой платформы (то есть 64-битного типа 64-битных систем).И обратите внимание, что
size_t
является целым типом без знака , аptrdiff_t
является целым типом со знаком . Этот тип подразумевает, что не все значенияsize_t
могут быть представленыptrdiff_t
.
Это, похоже, проблема в самом стандарте C.
Как вы заметили, 6.5.6 Аддитивные операторы , пункт 9 , в частности, гласит:
Когда вычитаются два указателя, оба должны указывать к элементам одного и того же объекта массива или одному последнему элементу объекта массива; Результатом является разница индексов двух элементов массива. Размер результата определяется реализацией, а его тип (целочисленный тип со знаком) определяется как
blockquote>ptrdiff_t
в заголовке<stddef.h>
. Если результат не может быть представлен в объекте этого типа, поведение не определено. Другими словами, если выраженияP
иQ
указывают соответственно наi
-й иj
-й элементы массива, выражение(P)-(Q)
имеет значениеi-j
[1123 ] при условии, что значение соответствует объекту типаptrdiff_t
. ...В стандарте C, похоже, нет гарантии, что вы можете представить разницу двух указателей в
ptrdiff_t
.Реально, это будет означать, что
ptrdiff_t
должно быть больше, чемsize_t
.size_t
должен покрывать только величину в фиксированном количестве битов.ptrdiff_t
должен охватывать как величину, так и направление. Еслиsizeof( size_t ) == sizeof( ptrdiff_t )
, то нет гарантии, что неопределенное поведение в 6.5.6p9 не будет вызвано.