c - 如何确定程序可以使用 unsigned long long 计算阶乘的最大值?

标签 c algorithm max factorial unsigned-long-long-int

如何在 C 中编写适当的算法来确定程序可以使用 unsigned long long int 计算阶乘的最大值?

我的例子不能正常工作。使用 Linux/64 位和 GCC,它给了我 65 次迭代。

#include <stdio.h>

int main() {
    unsigned long long int num, i;
    unsigned long long int factorial = 1;
    num = 1;
    for (i = 1; i <= num; i++) {
        factorial = factorial * i;
        num++;
        if (factorial <= 0) {
           printf("\nMaximum number is: %d\n", i - 1);
           break;
        }
    }
}

最佳答案

您的程序无法正常运行,因为:

  • factorial 总是 >= 0 因为它有一个无符号类型。程序停止的唯一原因是 factorial 在您乘以 2 或 2 的倍数足够多的次数后最终变为 0
  • 您无法通过测试结果值来可靠地检测溢出:无符号算术以值位数的 2 为模执行,因此您可以将结果与前一个阶乘进行比较,如果较小则中断。但是请注意,有符号算术溢出实际上具有未定义的行为,因此测试结果是否定的总是错误的。

更可靠的方法是在执行乘法之前检查溢出:

#include <limits.h>
#include <stdio.h>

int main(void) {
    unsigned long long int i, factorial;
    for (i = factorial = 1; factorial <= ULLONG_MAX / i; i++) {
        factorial = factorial * i;
    }
    printf("\nMaximum number is: %llu! = %llu\n", i - 1, factorial);
    return 0;
}

输出:

Maximum number is: 20! = 2432902008176640000

关于c - 如何确定程序可以使用 unsigned long long 计算阶乘的最大值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47244227/

相关文章:

c - 接收方的延迟 ACK 与发送方的 RTO

php - 在数组中查找总和等于给定数字的组合)元素总和

python - 获取二维网格(多维列表)中具有最大值的所有图 block

arrays - Swift数组中最大值及其索引的高效算法

c - & 运算符在结构上不做任何事情?

c - 当程序员意识到这是不好的风格但有必要时,注释应该说什么

java - 求两个元素之和的最小绝对值

java - 二叉搜索树 insert() 和 removeMin()

python - 如何返回字典中最大的浮点值?

c++ - C/CUDA程序输出