我使用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;
}
答案 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)
答案 4 :(得分:0)
对于这个purporse,您需要实现BigInteger。当前的c ++中没有这样的内置支持。您可以在stack overflow
上查看一些建议或者你也可以使用像GMP
这样的库此处还有一些实现:
答案 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
太大对于无符号的长期。