Path: csiph.com!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: Tim Rentsch
Newsgroups: comp.lang.c
Subject: Re: Recursion v Memoization
Date: Thu, 31 Dec 2020 00:46:03 -0800
Organization: A noiseless patient Spider
Lines: 54
Message-ID: <861rf6uzw4.fsf@linuxsc.com>
References:
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Info: reader02.eternal-september.org; posting-host="cb646d62786edb6c079bbfa1e5ebfce0"; logging-data="18060"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+6B/lVMYXTpko1MJscnTR7ZPBIzH07rkA="
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:v2mtyIVh9dGtF3THW0y9JYrQZkY= sha1:TXnpdqjt3YHjq26ckEAZP0of7R0=
Xref: csiph.com comp.lang.c:157930
Real Troll writes:
> We sometimes resort to using simple methods such as Recursion
> functions or interactive functions but Memoization method can be
> very useful. For example to generate 45 Fibonacci numbers using
> recursion I used this function:
>
> int fibonacci(int input)
> {
> if (input == 0 || input == 1)
> {
> return input;
> }
> else
> {
> return fibonacci(input - 1) + fibonacci(input - 2);
> }
> }
>
> but using an array to store the numbers and to reuse the previous
> calculated values can save a lot of time. [...]
Better simply to use a non-exponential algorithm:
/*** cut here ***/
#include
typedef unsigned long long ULL;
static ULL fibonacci( unsigned );
static ULL ff2( ULL, ULL, unsigned, unsigned );
int
main( int argc, char *argv[] ){
unsigned n;
for( n = 0; n < 94; n++ ){
ULL fn = fibonacci( n );
if( argc > 1 ) printf( " fib( %2u ) is %25llu\n", n, fn );
}
return 0;
}
ULL
fibonacci( unsigned n ){
unsigned high_bit = -1U ^ -1U>>1;
return ff2( 1, 0, high_bit, n );
}
ULL
ff2( ULL a, ULL b, unsigned m, unsigned n ){
return m == 0 ? b
: m & n ? ff2( 2*a*b + b*b, a*a + 2*a*b + 2*b*b, m>>1, n )
: ff2( a*a + b*b, 2*a*b + b*b, m>>1, n );
}