阶乘函数给出负数 no

0 c++ factorial

所以我用 C++ 编写了一个程序,该程序应该无休止地打印从 1 开始的数字的阶乘。它按预期打印了第一个数字,并具有正确的阶乘值,但之后它最终得到负值,并且程序由于提到的条件而终止。但我不确定一个良好的阶乘程序最终如何得到负值。

#include<iostream>
using namespace std;
int main(){
    int a = 1;
    int c = 1;
    while(a>0){
        cout<<(a*c)<<endl;
       
        a = a*c;
        c = c+1;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我期待阶乘从 1 到永远的无穷结果。

我得到的结果是——

#include<iostream>
using namespace std;
int main(){
    int a = 1;
    int c = 1;
    while(a>0){
        cout<<(a*c)<<endl;
       
        a = a*c;
        c = c+1;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Chr*_*ris 5

int是有符号类型。你的阶乘变得足够大以溢出(超过可以存储的最大值)int。当它们溢出时,你开始看到似乎没有意义的答案。

通过一个简单的演示程序可以很容易地看出这一点:

$ cat test.cpp
#include <iostream>
#include <iomanip>
#include <limits.h>

int factorial(int n) {
    int result = 1;
    for (; n > 1; n--) result *= n;
    return result;
}

int main() {
    for (int i = 1; i < 20; i++) {
        std::cout << std::setw(10) << std::right
                  << factorial(i) << std::endl
                  << INT_MAX << " <- max " << std::endl;
    }
}
$ g++ test.cpp
$ ./a.out
         1
2147483647 <- max
         2
2147483647 <- max
         6
2147483647 <- max
        24
2147483647 <- max
       120
2147483647 <- max
       720
2147483647 <- max
      5040
2147483647 <- max
     40320
2147483647 <- max
    362880
2147483647 <- max
   3628800
2147483647 <- max
  39916800
2147483647 <- max
 479001600
2147483647 <- max
1932053504
2147483647 <- max
1278945280
2147483647 <- max
2004310016
2147483647 <- max
2004189184
2147483647 <- max
-288522240
2147483647 <- max
-898433024
2147483647 <- max
 109641728
2147483647 <- max
Run Code Online (Sandbox Code Playgroud)

如果您想查看更大的阶乘结果,则需要使用更大的整数类型,并且可能需要使用更大的无符号整数类型。

如果我们这样做,我们就会为自己购买一些额外的空间来生成更大的阶乘。

$ cat test.cpp
#include <iostream>
#include <iomanip>

unsigned long long int factorial(int n) {
    unsigned long long int result = 1;
    for (; n > 1; n--) result *= n;
    return result;
}

int main() {
    for (int i = 1; i < 20; i++) {
        std::cout << std::setw(19) << std::right
                  << factorial(i) << std::endl
                  << ULONG_LONG_MAX << " <- max " << std::endl;
    }
}
$ g++ test.cpp
$ ./a.out
                  1
9223372036854775807 <- max
                  2
9223372036854775807 <- max
                  6
9223372036854775807 <- max
                 24
9223372036854775807 <- max
                120
9223372036854775807 <- max
                720
9223372036854775807 <- max
               5040
9223372036854775807 <- max
              40320
9223372036854775807 <- max
             362880
9223372036854775807 <- max
            3628800
9223372036854775807 <- max
           39916800
9223372036854775807 <- max
          479001600
9223372036854775807 <- max
         6227020800
9223372036854775807 <- max
        87178291200
9223372036854775807 <- max
      1307674368000
9223372036854775807 <- max
     20922789888000
9223372036854775807 <- max
    355687428096000
9223372036854775807 <- max
   6402373705728000
9223372036854775807 <- max
 121645100408832000
9223372036854775807 <- max
Run Code Online (Sandbox Code Playgroud)