フィボナッチ数列
結城浩さんのミルカさんとフィボナッチ数列を読んでみた。すげー、フィボナッチ数列って一般項にできるんだなぁと思って3バージョンほど作って比較。
再帰を使ったバージョンは40項にもなるとかなり遅いんだけど、一般項はsqrt()関数を使ってもオーバーフローするまで*1丸め誤差の影響は出ないなぁ。
以下にソース公開。
fibonacci.c
#include <stdio.h> #include "fibonacci.h" int fibonacci3(int n); int main(void){ int n; while(1){ printf("input n = "); scanf("%d",&n); if(n<0)break; printf("fibonacci(%d) = %d\n",n,fibonacci(n)); printf("fast_fibonacci(%d) = %d\n",n,fast_fibonacci(n)); printf("general_fibonacci3(%d) = %d\n",n,general_fibonacci(n)); } puts("exit."); return 0; }
fibonacci.h
/* * フィボナッチ数列の第n項を返す関数 * n < 0 にはFIB_FAILURE を返す。 * by Yuta 2005/10/23/ */ #include <math.h> #define FIB_FAILURE -1 /* 再帰版 */ int fibonacci(int n){ if(n<0)return FIB_FAILURE; if(n==0)return 0; if(n==1)return 1; return fibonacci(n-1) + fibonacci(n-2); } /* ループ版 */ int fast_fibonacci(int n){ int i; int a = 0; int b = 1; if(n<0)return FIB_FAILURE; if(n==0)return 0; if(n==1)return 1; for(i=0;i<n;i++){ b += a; a = b - a; } return a; } /* 一般項版 */ int general_fibonacci(int n){ double ret = ((pow(1.0 + sqrt(5), n) - pow(1.0 - sqrt(5), n)) / (pow(2,n) * sqrt(5))); if(n<0)return FIB_FAILURE; return (int)ret; }
*1:n=46