用c ++或c语言打印fibo大数字

时间:2015-12-18 10:33:18

标签: c++ c recursion fibonacci

我使用recursion为show fibonacci系列编写此代码。但是对于n> 43(例如:对于n = 100显示:-980107325),它没有正确显示。

#include<stdio.h>
#include<conio.h>

void fibonacciSeries(int);

void fibonacciSeries(int n)
{
static long d = 0, e = 1;
long c;
if (n>1)
{
    c = d + e;
    d = e;
    e = c;
    printf("%d \n", c);
    fibonacciSeries(n - 1);
}
}

int main()
{
long a, n;
long long i = 0, j = 1, f;
printf("How many number you want to print in the fibonnaci series :\n");
scanf("%d", &n);

printf("\nFibonacci Series: ");
printf("%d", 0);
fibonacciSeries(n);
_getch();
return 0;
}

6 个答案:

答案 0 :(得分:5)

fib(100)的值太大,即使是64位数也会溢出。要对如此大的值进行操作,您需要执行arbitrary-precision arithmetic。 C和C ++标准库不提供任意精度算术,因此您需要自己实现它或使用其他人编写的库。

对于适合您long long的较小值,您的问题是您使用了错误的printf格式说明符。要打印long long,您需要使用%lld

答案 1 :(得分:3)

代码溢出了使用的整数范围long 可以使用long long,但即使这样也可能无法处理至少需要69位的Fib(100)

如果long double

,代码可以使用1.0/LDBL_EPSILON > 3.6e20

存在各种库来处理非常大的整数。

对于此任务,所需的只是添加两个大整数的方法。考虑使用字符串。接下来是一个低效但简单的字符串添加。缓冲区溢出没有意外情况。

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

char *str_revese_inplace(char *s) {
  char *left = s;
  char *right = s + strlen(s);
  while (right > left) {
    right--;
    char t = *right;
    *right = *left;
    *left = t;
    left++;
  }
  return s;
}

char *str_add(char *ssum, const char *sa, const char *sb) {
  const char *pa = sa + strlen(sa);
  const char *pb = sb + strlen(sb);
  char *psum = ssum;
  int carry = 0;
  while (pa > sa || pb > sb || carry) {
    int sum = carry;
    if (pa > sa) sum += *(--pa) - '0';
    if (pb > sb) sum += *(--pb) - '0';
    *psum++ = sum % 10 + '0';
    carry = sum / 10;
  }
  *psum = '\0';
  return str_revese_inplace(ssum);
}

int main(void) {
  char fib[3][300];
  strcpy(fib[0], "0");
  strcpy(fib[1], "1");
  int i;
  for (i = 2; i <= 1000; i++) {
    printf("Fib(%3d) %s.\n", i, str_add(fib[2], fib[1], fib[0]));
    strcpy(fib[0], fib[1]);
    strcpy(fib[1], fib[2]);
  }
  return 0;
}

输出

Fib(  2) 1.
Fib(  3) 2.
Fib(  4) 3.
Fib(  5) 5.
Fib(  6) 8.
...
Fib(100) 3542248xxxxxxxxxx5075.  // Some xx left in for a bit of mystery.

Fib(1000) --> 43466...about 200 more digits...8875

答案 2 :(得分:0)

请记住,第n个斐波那契数是(大约)((1 + sqrt(5))/2)^n

这允许您获取n的值,该值允许结果适合32/64无符号整数。对于签名记得你丢了一点。

答案 3 :(得分:0)

好吧,您可以尝试在C ++或C中实现BigInt。

有用的材料:

答案 4 :(得分:0)

对于这个purporse,您需要实现BigInteger。当前的c ++中没有这样的内置支持。您可以在stack overflow

上查看一些建议

或者你也可以使用像GMP

这样的库

此处还有一些实现:

  1. E-maxx - 关于俄语描述。

  2. 或者在GitHub

  3. 上找到一些公开的实施方案

答案 5 :(得分:0)

Try to use a different format and printf,使用unsigned来获取更宽范围的数字。

如果你使用unsigned long long,你应该到18 446 744 073 709 551 615,直到第93个数字为斐波那契系列12200160415121876738,但在此之后你会得到不正确的结果,因为第94个数字19740274219868223167 太大对于无符号的长期。