【问题标题】:factorial int value in CC中的阶乘int值
【发布时间】:2020-03-28 15:25:41
【问题描述】:

所以我最近一直在用 C 语言做一个家庭学校项目。我们被要求编写代码来返回你输入的数字的阶乘。这很酷很简单,但我们也被要求做一些事情,什么会如果阶乘数大于整数的最大值,则给您写一个错误。

int main() {
int a, i;
int faktorial = 1;
a = 10;


if (a < 0)
    printf("Chyba, faktorial z nekladneho cisla neexistuje. \n");
else {
    for (i = 1; i <= a; ++i) {
        faktorial *= i;
    }
    printf("Faktorial z %d = %d\n", a, faktorial);

}

return 0;

}

这是我的代码,它运行良好,除非阶乘的值大于 int 的值。我尝试制作 if 语句,例如 if (faktorial > 2147483647) 而不是 printf 错误消息,但它只是没有工作,它仍然使 faktorial = 0。

【问题讨论】:

  • 你可以检查之前乘法,例如if(INT_MAX / i &lt; faktorial) {/* will overflow */}
  • 请记住,C 中的整数溢出会产生未定义的行为,因此您需要设计代码,以便检查每个操作是否会溢出在执行操作之前。不能先计算,然后再检查是否溢出。
  • 一个 32 位整数最多可以存储 12 个阶乘!一个 64 位整数可以存储多达 20 个的阶乘!一个 128 位(无符号)整数可以存储多达 34 个的阶乘!一个 256 位整数可以存储多达 57 个的阶乘!一个 512 位(无符号)整数可以存储多达 98 个阶乘!您可能没有一个编译器可以处理大于 64 位整数的大小(尽管 GCC 对 128 位整数有基本的支持)。

标签: c factorial


【解决方案1】:

您无法用&gt; 测试阶乘是否大于INT_MAX,因为int 永远不会大于INT_MAX。相反,您可以事先将INT_MAX 除以a,然后检查faktorial 是否大于此值。这样您就不必在每次迭代中进行划分:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
/* ... */
    int bound = INT_MAX / a;
    for (i = 1; i <= a; ++i) {
        if(faktorial > bound)
        {
            fputs("Integer Overflow!\n", stderr);
            return EXIT_FAILURE;
        }
        faktorial *= i;
    }

假设a 是严格肯定的,这将始终有效。

【讨论】:

  • 是的,我按照 Weather Vane 先生的建议做了这个,效果很好,谢谢。
  • 我只是错过了重点,它永远不会大于最大值,我的错。
  • 我建议测试INT_MAX/a,因为整数除法很慢。如果执行具有相同分母的多个除法,则足够先进的编译器可以将它们转换为乘法逆运算(尽管我还没有看到编译器对非常数分母执行此操作)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-13
  • 1970-01-01
  • 2021-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多