C打印第一百万斐波纳契数

时间:2015-11-16 10:49:35

标签: c fibonacci

我正在尝试编写将打印前100万斐波那契数字的C代码。

实际问题是我想获得 lats 10位数字F(1,000,000)

我理解序列是如何工作的,以及如何编写代码来实现它,但是F(1,000,000)非常大,我很难找到一种方法来代表它。

这是我正在使用的代码:

#include<stdio.h>

int main()
{
   unsigned long long n, first = 0, second = 1, next, c;

   printf("Enter the number of terms\n");
   scanf("%d",&n);

   printf("First %d terms of Fibonacci series are :-\n",n);

   for ( c = 0 ; c < n ; c++ )
   {
      if ( c <= 1 )
         next = c;
      else
      {
         next = first + second;
         first = second;
         second = next;
      }
      printf("%d\n",next);
   }

   return 0;
}

我正在使用long long尝试确保有足够的位来存储数字。

这是第一个100数字的输出:

First 100 terms of Fibonacci series are :-                                                                                                                                     

    0                                                                                                                                                                              
    1                                                                                                                                                                              
    1                                                                                                                                                                              
    2                                                                                                                                                                              
    3                                                                                                                                                                              
    5                                                                                                                                                                              
    8                                                                                                                                                                              
    13                                                                                                                                                                             
    21                                                                                                                                                                             
    34                                                                                                                                                                             
    55                                                                                                                                                                             
    89                                                                                                                                                                             
    144                                                                                                                                                                            
    233                                                                                                                                                                            
    377                                                                                                                                                                            
    610                                                                                                                                                                            
    987                                                                                                                                                                            
    1597                                                                                                                                                                           
    2584                                                                                                                                                                           
    4181                                                                                                                                                                           
    6765                                                                                                                                                                           
    10946                                                                                                                                                                          
    17711                                                                                                                                                                          
    28657                                                                                                                                                                          
    46368                                                                                                                                                                          
    75025                                                                                                                                                                          
    121393                                                                                                                                                                         
    196418                                                                                                                                                                         
    317811                                                                                                                                                                         
    514229                                                                                                                                                                         
    832040                                                                                                                                                                         
    1346269                                                                                                                                                                        
    2178309                                                                                                                                                                        
    3524578                                                                                                                                                                        
    5702887                                                                                                                                                                        
    9227465                                                                                                                                                                        
    14930352                                                                                                                                                                       
    24157817                                                                                                                                                                       
    39088169                                                                                                                                                                       
    63245986
    102334155                                                                                                                                                                      
    165580141                                                                                                                                                                      
    267914296                                                                                                                                                                      
    433494437                                                                                                                                                                      
    701408733                                                                                                                                                                      
    1134903170                                                                                                                                                                     
    1836311903                                                                                                                                                                     
    -1323752223                                                                                                                                                                    
    512559680                                                                                                                                                                      
    -811192543                                                                                                                                                                     
    -298632863                                                                                                                                                                     
    -1109825406                                                                                                                                                                    
    -1408458269
    ...

截断输出但你可以看到问题,我相信生成的数字的大小导致值溢出为负。我不明白如何诚实地制止它。

有人能指出我如何真正处理这个数量的数字吗?

我没有尝试打印第一百万,因为如果打印失败F(100),则打印F(1,000,000)的希望不大。

5 个答案:

答案 0 :(得分:7)

你想要Fib(1000000)的最后10位数。阅读有关Fibonacci numbers的更多信息(并阅读两次)。

如果不加思索,可以使用bignum之类的GMPlib库。你可以使用几个 mpz_t bigint变量来循环计算Fib(1000000)(你当然不需要一个百万mpz_t的数组,但更少{{1}你手里拿着手指的变量。当然,你不会打印所有的斐波那契数字,只有最后的1000000 th 一个(所以今天便宜的笔记本电脑有足够的内存,并且会在不到一个小时内吐出这个数字)。作为John Coleman answered,它有大约200K的数字(即2500行,每行80位)。

(顺便说一下,当考虑一个产生一些大输出的程序时,你最好猜测 - 估计输出的典型大小和获得它的典型时间;如果它不适合你的桌面室 - 或者你的台式电脑 - 你有一个问题,也许是一个经济问题:你需要购买更多的计算资源)

请注意,有效的bignum算法是一门难题。 bignum算法存在聪明的算法,它比你想象的天真算法更有效。

实际上,你不需要任何重要的事情。阅读一些关于modular arithmetic的数学教科书。和(或乘积)的模数与模量的和(相应的乘积)一致。使用该属性。一个10位整数适合64位mpz_t,所以有些人认为你不需要任何bignum库。

(我想更多的想法,你不需要任何计算机或任何C程序来计算它。一个便宜的计算器,一支铅笔和一张纸应该足够了,可能不需要计算器完全没有。)

在编程时(或在解决数学练习时)要学习的教训是考虑问题在开始编码之前尝试重新构建问题。 J.Pitrat(法国的人工智能先驱,现已退休,但仍在他的电脑上工作)有几个有趣的blog条目:Is it possible to define a problem?When Donald and Gerald meet Robert等。

理解和思考问题(以及子问题!)是软件开发的一个有趣部分。如果您从事软件开发工作,首先会要求您解决实际问题(例如,制作销售网站或自动吸尘器),您需要考虑将问题转化为可编码的问题。电脑。请耐心等待,你需要ten years to learn programming

答案 1 :(得分:5)

要“获取F(1,000,000)的最后10位数”,只需在计算%时应用余数函数next并使用正确的格式说明符:"%llu"

没有必要对比10个最低有效数字更重要的数字求和。

  // scanf("%d",&n);
  scanf("%llu",&n);
  ...
  {
     // next = first + second;
     next = (first + second) % 10000000000;
     first = second;
     second = next;
  }
  // printf("%d\n",next);
  printf("%010llu\n",next);

我的输出(x后面的最后5位数字没有给出最终答案)

 66843xxxxx

答案 2 :(得分:4)

通过Binet's Formula,第n个斐波那契数大约是上升到幂n的黄金比率(大约1.618),然后除以5的平方根。对数的简单使用表明第百万个斐波那契数具有超过200,000位数。因此,第一百万斐波纳契数中的一个的平均长度超过100,000 = 10 ^ 5。因此,您正在尝试打印10 ^ 11 = 1000亿个数字。我认为你需要的不仅仅是一个大的int库。

另一方面 - 如果你想简单地计算百万分之一的数字,你可以这样做 - 尽管使用一种不计算所有中间数的方法会更好(简单地计算而不是打印它们对于足够大的n)来说仍然是不可行的。众所周知(见this)第n个斐波那契数是矩阵[[1,1],[1,0]]的n次幂的4个项之一。如果你使用exponentiation by squaring(因为矩阵乘法也是关联的,因为矩阵乘法是关联的)和一个好的大型int库 - 计算百万分之一的Fibonacci数就变得完全可行了。

[On Further Edit]:这是一个Python程序,用于计算非常大的Fibonacci数,修改为现在接受可选模数。在引擎盖下,它使用了一个很好的C bignum库。

def mmult(A,B,m = False):
    #assumes A,B are 2x2 matrices
    #m is an optional modulus
    a = A[0][0]*B[0][0] + A[0][1]*B[1][0]
    b = A[0][0]*B[0][1] + A[0][1]*B[1][1]
    c = A[1][0]*B[0][0] + A[1][1]*B[1][0]
    d = A[1][0]*B[0][1] + A[1][1]*B[1][1]
    if m:
        return [[a%m,b%m],[c%m,d%m]]
    else:
        return [[a,b],[c,d]] 

def mpow(A,n,m = False):
    #assumes A is 2x2
    if n == 0:
        return [[1,0],[0,1]]
    elif n == 1: return [row[:] for row in A] #copy A
    else:
        d,r = divmod(n,2)
        B = mpow(A,d,m)
        B = mmult(B,B,m)
        if r > 0:
            B = mmult(B,A,m)
        return B

def Fib(n,m = False):
    Q = [[1,1],[1,0]]
    return mpow(Q,n,m)[0][1]

n = Fib(999999)
print(len(str(n)))
print(n % 10**10)
googol = 10**100
print(Fib(googol, googol))

输出(添加空格):

208988

6684390626

3239047153240982923932796604356740872797698500591032259930505954326207529447856359183788299560546875

请注意,你称之为百万分之一的斐波纳契数,我称之为第999,999号 - 因为从1开始作为第一个斐波那契数是更标准的(如果你想把它算作斐波那契数,则把0调到0) )。第一个输出数字确认数字中有超过200,000个数字,第二个输出最后10个数字(这不再是一个谜)。最终的数字是googolth斐波那契数的最后100位数 - 在很短的一秒钟内计算出来。我还没能做googolplex:)

答案 3 :(得分:3)

这个问题毫无疑问来自某些编程竞赛,你必须仔细阅读这些问题。

第100万斐波纳契数是巨大的。可能大约200,000位数左右。打印第一个1,000,000斐波那契数将杀死整个森林树木。但请仔细阅读:没有人问你第100万个斐波那契数字。系统会要求您输入该号码的最后十位

因此,如果你有Fib(n-2)和Fib(n-1)的最后10位数,你怎么能找到Fib(n)的最后10位数?如何在不计算数字本身的情况下计算斐波纳契数的最后十位数?

PS。您无法使用%d打印长的长号码。使用%lld。

答案 4 :(得分:1)

您的算法实际上是正确的。由于你使用unsigned long long,你有足够的数字来捕获最后10位数字和无符号溢出函数的性质作为模运算,因此你至少可以得到正确的结果10位数。

问题在于您用于输出的格式说明符:

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

%d格式说明符需要int,但您传递unsigned long long。使用错误的格式说明符调用undefined behavior

在这种特殊情况下最有可能发生的事情是printf正在拾取next的低4字节(因为您的系统似乎是小端)并解释它们作为签名int。最终显示大约前60个数字左右的正确值,但之后不正确。

使用正确的格式说明符,您将获得正确的结果:

printf("%llu\n",next);

阅读/打印时,您还需要执行相同操作n

scanf("%llu",&n);

printf("First %llu terms of Fibonacci series are :-\n",n);

这里是数字45-60的输出:

701408733
1134903170
1836311903
2971215073
4807526976
7778742049
12586269025
20365011074
32951280099
53316291173
86267571272
139583862445
225851433717
365435296162
591286729879
956722026041