return 和 printf unsigned long 的问题

Problem to return and printf unsigned long

我不明白为什么我的代码仍在打印 int 值(溢出)而我想要 unsigned long 值!

这是我的代码:

#include <stdio.h>

unsigned long factorial(int num) {
    if ((num == 0) || (num == 1 )) {
        return 1;
    } else if (num < 0) {
        return 0;
    } else {
        return num * factorial(num - 1);
    }
}

int main(void) {
    int num;
    char liste;
    printf("Choisir un nombre pour trouver son factoriel : ");
    //Translation : "Choose a number to find its factorial" 
    scanf("%d", &num);
    printf("factoriel de %d : %lu\n", num, factorial(num));
}

这是 return 阶乘值的非常基本的代码,但我只是初学者。

阶乘函数增长非常快。几乎无论您使用什么类型进行计算,它都会很快溢出。

在类型 unsigned long 有 32 位的机器上(这是可以保证的),您的程序可以正确计算 12! = 479001600(但没有更大)。我怀疑这就是你所看到的。

在类型 unsigned long 有 64 位的机器上,您的程序可以正确计算 20! = 2432902008176640000。(我的机器有 64 位 longs,我用你的程序计算了这个结果,它运行良好。)

所以你的程序其实没问题;我看不出有什么问题。 (好吧,评论中有一个未使用的变量 liste,还有一条面包。:-))

如果你的编译器和 C 库都支持 long long 类型,你可以试试这个来增加你机器上的范围:

#include <stdio.h>

unsigned long long factorial(int num) {
    if (num < 0) {
        return 0;
    } else if (num <= 1 ) {
        return num;
    } else {
        return num * factorial(num - 1);
    }
}

int main(void) {
    int num;
    printf("Choisir un nombre pour trouver son factoriel : ");
    scanf("%d", &num);
    printf("factoriel de %d : %llu\n", num, factorial(num));
}

但是,同样,这最多只能让您达到 20!。 (在这个版本中,我还略微清理了 factorial 函数的逻辑。)

如果%llu不行,你可以试试%Lu

一些编译器支持 128 位类型(我认为 gcc 称之为 _uint128_t 或类似的东西),理论上这可以让你达到 34 位! = 295232799039604140847618609643520000000.

但除此之外,您还必须使用“多精度”或“任意精度”库,例如 GMP. For example, 100! has 525 bits, and 1000! has 8530 bits