所以我写了一个简单的C程序,根据用户规范显示第n个斐波纳契数。我开始使用整数并显然没有太好用,所以我去了花车,多头,最后很长。即使有很长的时间,也会出现切断,我会得到无意义或不正确的输出,例如负数(在n = 100之前开始发生)。有什么办法可以扩展这个程序的范围,还是没办法解决这个问题?
#include <stdio.h>
#include <stdlib.h>
int main()
{
long long term = 0;
long long val = 0;
long long first = 0;
long long second = 1;
printf( "Which fibonacci term (starting at 0) would you like to see? ");
scanf("%lld", &term );
if( term == 0 )
{
printf("%lld\n", first );
return 1;
}
if( term == 1 )
{
printf( "%lld\n", second );
return 1;
}
if( term > 1 )
{
for( int i = 1; term > i; i++ )
{
val = first + second;
first = second;
second = val;
}
printf( "%lld\n", val );
return 1;
}
return 0;
}
答案 0 :(得分:4)
根据ISO C99,long long最小为64位 - 具有最大大小的标准整数数据类型。您的编译器可能允许更大的类型,这些类型由intmax_t
中的uintmax_t
和<stdint.h>
定义。
但是,我强烈建议使用Bigint库,例如GMP。 使用GMP,长整数和浮点的唯一限制是系统上可用的资源。
答案 1 :(得分:1)
将所有类型更改为unsigned long long
,这将执行无符号算术,几乎使范围加倍。如果您希望进一步扩展,则需要创建自己的数据类型。可以为您执行此操作的库的一些示例:
编辑每个Michael Burr的评论:
答案 2 :(得分:0)
可以使用uintmax_t
,但这可能是&lt; = 128位。
GMP是一个值得考虑的优秀图书馆。
但是只需要编写一个扩展精度add()
,如下所示。效率不高,但它可以完成fib()
的工作。这里我使用C字符串作为数据类型。其他类型的设计可以更好地工作。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define max(a, b) ((a) > (b) ? (a) : (b))
// "Add" 2 strings
char *strsum(const char *a, const char *b) {
size_t alen = strlen(a);
size_t blen = strlen(b);
size_t clen = max(alen, blen) + 1;
size_t csize = clen + 1;
char *c = malloc(csize);
if (c == NULL) return NULL;
c[clen] = '\0';
int carry = 0;
while (alen > 0 && blen > 0) {
int sum = a[--alen] - '0' + b[--blen] - '0' + carry;
c[--clen] = sum%10 + '0';
carry = sum / 10;
}
while (alen > 0) {
int sum = a[--alen] - '0' + carry;
c[--clen] = sum%10 + '0';
carry = sum / 10;
}
while (blen > 0) {
int sum = b[--blen] - '0' + carry;
c[--clen] = sum%10 + '0';
carry = sum / 10;
}
if (carry) {
c[--clen] = carry + '0';
}
if (clen > 0) {
memmove(&c[0], &c[1], csize - 1);
}
return c;
}
void fib(unsigned n) {
char *a = NULL;
char *b = malloc(2); strcpy(b, "0");
char *c = malloc(2); strcpy(c, "1");
unsigned i;
for (i=1; i<n; i++) {
free(a);
a = b;
b = c;
c = strsum(a, b);
if (c == NULL) break;
printf("fib(%u) = %s\n", i+1, c);
}
free(a);
free(b);
free(c);
}
int main(int argc, char *argv[]) {
fib(1000);
return 0;
}
样品
fib(2) = 1
fib(3) = 2
fib(4) = 3
fib(5) = 5
fib(6) = 8
fib(7) = 13
fib(8) = 21
fib(9) = 34
fib(10) = 55
...
fib(93) = 12200160415121876738 /* max using 64-bit math */
...
fib(100) = 354224848179261915075
...
fib(1000) = 43466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875
...
fib(10000) = 336...(2084 digits)...875