C中最大的数字数据类型

时间:2014-06-06 23:13:48

标签: c types numbers

所以我写了一个简单的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;

}

3 个答案:

答案 0 :(得分:4)

根据ISO C99,long long最小为64位 - 具有最大大小的标准整数数据类型。您的编译器可能允许更大的类型,这些类型由intmax_t中的uintmax_t<stdint.h>定义。

但是,我强烈建议使用Bigint库,例如GMP。 使用GMP,长整数和浮点的唯一限制是系统上可用的资源。

答案 1 :(得分:1)

将所有类型更改为unsigned long long,这将执行无符号算术,几乎使范围加倍。如果您希望进一步扩展,则需要创建自己的数据类型。可以为您执行此操作的库的一些示例:

编辑每个Michael Burr的评论:

  • 要求您的平台具有大于64位的无符号长整数,例如128位(或更多)。 C99仅保证long long 至少 64位。如果long long只有64位,那么你的特定程序的范围不会改变。

答案 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