且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

动态规划问题 - Fibonacci序列

更新时间:1970-01-01 07:55:06

有了这样大的数字,你得到一个无符号整数溢出,从而导致环绕导致操作,模原结果 1 LT;<位,比特属于特定整数类型的位宽。如果你想重新present这些数字,你必须使用某种BIGNUM库,如 GNU GMP。一>

I was reading this Wikipedia article, and attempting to implement a 'map' based solution in C, where a 'map' is just an int array, initialized to 0.

For some reason it works up to fib(93), then starts outputting strange numbers. If it matter's I'm specifying -std=c99:

#include <stdio.h>
#include <stdlib.h>

// represents a fib num
typedef unsigned long long fib_t;

// the default value of our 'map'
const int FIB_NULL   = 0;

// could get from input, set here for now
const int FIB_MAX    = 100;

// our 'map' for fib nums
static fib_t *fibMap;

// calculate the fib num n
fib_t fib( unsigned int n )
{
    // if this num, n, is not 0 or 1, and is FIB_NULL, then calculate it
    if( n > 1 && FIB_NULL == fibMap[n] )
    {
        fibMap[n] = fib( n-1 ) + fib( n-2 );
    }

    // get it from the map
    return fibMap[n];
}

// used to setup the 'map' for the fibs
static void initFibMap()
{
    // emulate a map
    fibMap = malloc( sizeof(fib_t) * FIB_MAX);

    // initialize it to 'null'
    memset(fibMap, FIB_NULL, sizeof(fib_t) * FIB_MAX);

    // by definition
    fibMap[0] = 0;
    fibMap[1] = 1;
}

int main(int argc, char *argv[]) 
{
    // setup our 'map'
    initFibMap();

    for( unsigned int i=0; i<FIB_MAX; i++ )
    {
        // breaks on 94
        printf("Fib #%d: %llu\n",i, fib(i));
    }
}

Strange output:

// . . .
// . . .
// Fib #90: 2880067194370816120  // good
// Fib #91: 4660046610375530309  // good
// Fib #92: 7540113804746346429  // good
// Fib #93: 12200160415121876738 // good
// Fib #94: 1293530146158671551  // WHAT?
// Fib #95: 13493690561280548289
// Fib #96: 14787220707439219840
// Fib #97: 9834167195010216513
// Fib #98: 6174643828739884737
// Fib #99: 16008811023750101250

With such large numbers, you're getting an unsigned integer overflow, which causes a "wrap around" to result in the original result of the operation, modulo 1 << bits, bits being the bit width of the particular integer type. If you want to represent these numbers, you have to use some kind of bignum library, such as the GNU GMP.