【问题标题】:Why am i not able to print 47th fibonacci number correctly?为什么我无法正确打印第 47 个斐波那契数?
【发布时间】:2016-08-28 15:25:31
【问题描述】:

我使用的是 64 位操作系统,那么我也无法正确打印小于 40 亿的第 46 个斐波那契数。

#include<cs50.h>
#include<stdio.h>

int main(void)
{  

    unsigned int n=50;
    int array[n];
    array[0]=0;
    array[1]=1;
    printf("%i\n",array[0]);
    printf("%i\n",array[1]);
    for(int i=2;i<n;i++)
    {
        array[i]=array[i-1]+array[i-2];
        printf("%i\n",array[i]);
    }

【问题讨论】:

  • int array[n]; printf("%i\n",array[i]); --> unsigned int array[n]; printf("%u\n",array[i]);
  • @kaylum unsigned int 在第 49 个元素处仍然超出范围。
  • @RishikeshRaje 是的,我说的是字面意思,因为问题是“为什么我不能打印 47th”。进行该更改将使 47th 可以正确打印。并且 OP 特别提到了“40 亿”,这似乎暗示 OP 知道 32 位数字的范围,因此可能期望在超过该数字时看到溢出,而不是之前。
  • @Kuldeep1007tanwar 不,不是。它是一个可变长度数组(VLA)。自 C99 以来它一直在 C 标准中(尽管在 C11 中成为可选)。
  • 哦对不起我的错误我误解了这个概念:-void temp_arr (const int array_size) { int temp_arr[array_size]; }

标签: c fibonacci cs50


【解决方案1】:

您必须使用 long long 作为数组的数据类型。因为您将存储整数范围的超出范围的数字。(-2,147,483,648 到 2,147,483,647) 并且 int i 的声明应该在 for 循环之前。

#include<stdio.h>

int main(void)
{

    int n=50;
    long long array[n];
    array[0]=0;
    array[1]=1;
    printf("%lli\n",array[0]);
    printf("%lli\n",array[1]);
    int i;
    for(i=2;i<n;i++)
    {
        array[i]=array[i-1]+array[i-2];
        printf("%lli\n",array[i]);
    }
}

【讨论】:

  • "并且 int i 的声明应该在 for 循环之前。" --> 从 C99 开始,for(int i=2;i&lt;n;i++) 还可以,long long 也被标准化了。
【解决方案2】:

我无法正确打印小于 40 亿的第 46 个斐波那契数。

您很可能超出了整数范围,即 -4294967296 到 4294967295。

int array[n]; 更改为long long array[n];

另外,printf 应该从 %i 更改为 %lli

编辑:在运行数字时,您会得到 F(48) 的预期值为 4807526976,它超出了整数范围。

【讨论】:

  • 带符号的 32 位数字的范围是 -2147483648 到 2147483647。
【解决方案3】:

使用 Rishikesh Raje 的计数系统(即第一个斐波那契为 1),其中 F(48) 为 4807526976,那么您无法获得 F(47) 2971215073,因为正如 @kaylum 评论的那样,您使用了一个有符号整数数组保留您需要更改为无符号的值,并更改您的 printf 语句以打印无符号。这将使您达到 32 位算术的极限:

#include <stdio.h>

#define LIMIT (50)

int main(void) {
    unsigned int array[LIMIT] = {0, 1};

    printf("%u\n", array[0]);
    printf("%u\n", array[1]);

    for (size_t i = 2; i < LIMIT; i++)
    {
        array[i] = array[i - 1] + array[i - 2];
        printf("%u\n", array[i]);
    }

    return 0;
}

要超过 32 位,您可以按照 Rishikesh Raje 的建议切换到 long 或 long long,但如果您想在给定位数的情况下达到最大结果,请使用无符号变体。

【讨论】:

    【解决方案4】:

    使用无符号整数数组或更高的值使用 unsigned long long long 数组,但您不需要数组来打印斐波那契数列,您可以简单地这样做:-

    void main()
    {
      unsigned long long i=1, num1=1, num2=0;
      printf("1 \n");
      for(i; i<100 ; i++)
       {
         num1=num1+num2;
         num2=num1-num2;
         printf("%lli \n", num1);
       }
      getch();
     }
    

    【讨论】:

      猜你喜欢
      • 2016-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-29
      • 2016-02-17
      • 1970-01-01
      • 2015-01-04
      相关资源
      最近更新 更多