繁体   English   中英

斐波那契函数在C中具有大数字(即1000个数字)

[英]Fibonacci function with big number (i.e. 1000 digits) in C

编辑:我替换:进位=(x-(x%10))%10; 通过:进位= x / 10;

我在while循环的末尾添加了add():if(carry)f3 [i] =进位;

感谢FalconUSA和M_Oehm! :)

我正在研究Euler项目的问题25(当心破坏者),虽然fibonacci函数并不是真正的问题,但我很难实现一种存储大量数字的方法(例如,那里有1000位数字)。

因此,我尝试(如在网络上学到的)使用数组处理它,但是该程序无限期地运行。 我的问题可能是addition()或length()。

有什么想法吗?

#include <stdio.h>
#include <string.h>

int length(int *nbr) // number of digits of my number
{
    int len = 0, c = 0;

    while(nbr[c] >= 0) {
        len++;
        c++;
    }
    return len;
}

int addition(int *f1, int *f2, int *f3, int siz) // add f1+f2 and store it in f3
{
    int carry =0, i =0;
    int x;

    memset ( f3, -1, siz*sizeof(int));

    while ( (f1[i] >= 0) || (f2[i] >= 0) ) {
        if(f1[i]<0) {
            x = f2[i] + carry;
        }
        else if(f2[i]<0) {
            x = f1[i] + carry;
        }
        else {
            x = f1[i] + f2[i] + carry;
        }
        f3[i] = x%10;
        carry = (x-(x%10))%10;
        i++;
    }

    return 0;
}

int copy_arr(int *dest, int *or, int siz) //copy array "or" into "dest"
{
    int c = 0;
    memset( dest, -1, siz*sizeof(int));

    while( c < siz ) {
        dest[c] = or[c];
        c++;
    }

    return 0;
}

int fibo(int siz) //fibonacci function
{
    int f1[siz],f2[siz],f3[siz];
    memset( f1, -1, siz*sizeof(int));
    memset( f2, -1, siz*sizeof(int));
    memset( f3, -1, siz*sizeof(int));

    int n = 2;

    f1[0] = f2[0] = 1;


    while (length(f1) <= siz) {
        n++;
        addition( f1, f2, f3, siz);
        copy_arr( f2, f1, siz);
        copy_arr( f1, f3, siz);
    }

    printf("%d\n", n);

    return 0;
}


int main() // siz's value is the number of digits I desire for my fibonacci number
{
    int siz=1000;

    fibo(siz);

    return 0;
}

您可以使用GMP多精度库: https : //gmplib.org 您可能还需要检查Fibonacci部分: https : //gmplib.org/manual/Fibonacci-Numbers-Algorithm.html

更新您可能还需要查看这篇文章,该文章演示了如何从头开始实现快速斐波那契: https : //www.anfractuosity.com/2012/10/24/fib-calculation-with-gmp

使用GMP的优点是,您将拥有真正快速且精心设计的算法,这些算法是由知道自己在做什么的人编写的。 GMP非常快(它是部分地用汇编语言编写的,并且充分利用了各种算法),成熟且稳定的库。 每当您需要处理大量数据时,使用GMP总是一个好主意。

好吧,看来您的问题出在这一行:

carry = (x - x%10) % 10;

应该只是

carry = x - x%10;

要么

carry = x / 10;

在这种情况下是等效的。

更新:还行

 while ( (f1[i] >= 0) || (f2[i] >= 0) ) {

如果f1的大小是sizf2的大小也是siz ,那么您将到达元素f1[siz] ,甚至更远,它超出范围 所以,你应该声明

int f1[siz+1], f2[siz+1], f3[siz+1]

并且您应该在各处设置siz+1边线:

memset( fi, -1, (siz+1)*sizeof(int)); // where 1 <= i <= 3

PS:如果您只想计算斐波那契数而不集成到需要快速计算的程序中,则最好使用PythonJava ,因为这些语言具有内置的长数字支持,并且它们的语法非常简单并且类似于C++ 而且,正如上面的ghostmansd所述,如果您仍然要使用C / C ++,最好使用GMP库

您的代码有几个问题。

您的号码以前哨值为-1的数字结尾。 您需要为多余的数字留出空间,就像您需要为C字符串中的空终止符留出空间一样。 您应该将数组的尺寸设置为siz + 1并初始化所有值,包括虚拟值。

当您将两个数字相加时,您永远不会考虑最后一个进位。 这意味着您的电话号码永远都不会更长。 addition ,将其添加到主折叠后:

if (carry) f3[i] = carry;

您确定进位的方法也不正确。 进位是左边的多余数字:

carry = x / 10;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM