【问题标题】:How do I increase the size of int, so that i could store the value of 5 ^ 30 in it如何增加 int 的大小,以便我可以在其中存储 5 ^ 30 的值
【发布时间】:2019-04-13 22:20:52
【问题描述】:

我正在尝试编写一个程序,要求将 5^30 的幂存储到 int 中,但是当我尝试这样做时,它会给出一个负数的输出。 双倍或长时它运行良好

#include <stdio.h>

int PowerFive(){

    int a, i, n=5, e=1;
    for (i = 0; i<=30; i++)
    {
        a=e;
        printf("%d, ", e);
        e = e*n;
    }

    return 0;
}

int main()
{
    PowerFive();
}

【问题讨论】:

  • 为什么要适合长篇? 30 * math.log(5) / math.log(2) = 69.66 &gt; 63.
  • 没有包含 5³⁰ 的标准整数大小 — bc 说:5^30 = 9313225746154785156252^63 = 9223372036854775808 并且 5^30 中的十进制数字比 2^ 中的多 2 个63.因此,您需要 64 位以上的整数来存储 5^30。您可以用 2 个 64 位数字模拟一个 128 位数字。
  • 您确定要求是“int 值”而不是“整数值”吗?

标签: c linux


【解决方案1】:

你不能; int 的大小是固定的。

long 可能大于int,但看起来您需要超过 64 位才能获得正确答案。在这种情况下,您最好的选择可能是使用__int128

【讨论】:

  • 是的,有,见评论。
  • 没错..我们使用了long,它可以工作,但要求是我们必须返回一个int值
  • 啊,我被 OP 误导了,说“双倍或长时运行良好”。在这种情况下,__int128 是……
  • 或者要求返回值是整数类型,不一定是int__int128 将符合整数类型。
【解决方案2】:

intlongdouble、...的位/字节数取决于实现/平台。

因此,在某些平台上,这可能不适用于 long

关于“它适用于double”的注释:通常,对于doublefloat,您可能认为它有效,但答案可能是错误的:四舍五入到接近正确答案的值。

您必须实现自己的 big-int 代码,该代码使用 3 个(或更多)ints。

【讨论】:

  • 可以用 Malloc 做点什么吗?
  • @AliAshar:由于您的代码没有使用malloc(),因此您遇到的问题与malloc() 无关。问题是您试图将 70 位数据放入 32 位值中,这根本不能很好地工作。
  • @AliAshar:简单地使用int 是行不通的,这是正确的。可以使用 3 个或 4 个 32 位 int 值创建一个结构来模拟 96 位或 128 位整数,然后使用该类型进行计算。您还需要考虑如何处理符号位(因此您可能使用unsigned int 而不是signed int)。但是使用int 类型的简单变量是行不通的。
【解决方案3】:

增加int的大小

编译器有时会提供int 大小的控件,但通常将其固定为目标系统的 32、16、64、.. 位。必须至少为 16。

存储5^30的值

530 是 931322574615478515625,一个 70 位的数字。

C 没有为此指定足够宽的整数类型,尽管某些系统确实支持 128 位整数。

缺少 128 位整数,存储该整数值需要不同的方法。存在各种任意宽度的库。

快速使用 字符串 - 效率不高,但可以完成工作。

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>

char *strmult(char *s, size_t size, unsigned char m) {
  size_t len = strlen(s);
  if (len >= size) {
    return NULL;
  }
  int carry = 0;
  for (size_t i = len; i-- > 0;) {
    if (!isdigit((unsigned char ) s[i])) {
      return NULL;
    }
    int sum = (s[i] - '0') * m + carry;
    s[i] = sum % 10 + '0';
    carry = sum / 10;
  }
  if (carry) {
    if (len + 1 >= size) {
      return NULL;
    }
    memmove(s + 1, s, len + 1);
    s[0] = carry + '0';
  }
  return s;
}

int main(void) {
  char s[100] = "1";
  for (int i = 0; i < 30; i++) {
    strmult(s, sizeof s, 5);
  }
  puts(s);
}

输出

931322574615478515625

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-08
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 2019-11-20
    • 1970-01-01
    相关资源
    最近更新 更多