简单的C ++阶乘程序

时间:2015-07-27 16:29:05

标签: c++ while-loop integer factorial

作为家庭作业我需要一个程序来读取非负整数并计算和打印它的阶乘。 到目前为止我编写了代码,但如果我尝试输入50!结果为0.它适用于较小的数字。任何帮助将不胜感激。

#include <iostream>

using namespace std;

int main()
{
    int counter = 1;
    int number;

    cout << "Please enter a number: ";
    cin >> number;

    int factorial = number;
    while (counter != number)
    {
        factorial = factorial * (number - counter);
        counter++;

    }

    cout << "The factorial of " << number << "! is: " << factorial << endl;
    return 0;
}

6 个答案:

答案 0 :(得分:9)

50!30414093201713378043612608166064768844377641568960512000000000000,对于int来说太大了。由于整数溢出,结果为0。

答案 1 :(得分:4)

如果要计算大因子,则需要使用一些BigInteger类。 看看这个:Thread

答案 2 :(得分:2)

已经有一些答案了。然而,他们都缺乏提供一些(imho)重要事实:

无论您选择多大的结果类型,您的程序将能够计算的内容始终存在限制。

正常口袋计算器69!是他们可以显示的最大因子(因为它是具有两位数指数的最大因子)。要求更大的东西只会导致错误或NaN。实际上这完全没问题,因为在实践中你很少需要具有完美精度的巨大因子。通常可以使用Stirlings近似或使用其他技巧来避免冗长的计算(顺便说一下69!对于袖珍计算器来说也是一个不错的基准,因为在较慢的计算器上它可能已经花了几秒钟。)

结论:您的代码完全可以合理输入。如果你真的需要寻求更高的阶乘,有办法,但我想你的任务并不是真的要求它。而且,无论你怎么做,你总是达到极限。因此,为了使你的代码“无bug”我会添加类似

的东西
assert(number < 50 && "Sorry, this number is too big");

在计算之前。

答案 3 :(得分:1)

选择较大范围的数据类型,该数据类型不会超过存储在变量'factorial'

中的值

您应将其声明为List<Person> t = new List<Person>();

现在,它显示为零,因为int(此处为signed),因此对于将int数据类型存储为2byte的系统,它的范围从-32568到+32567。 在修饰符“long long”的帮助下,实际上将其存储字节增加到8字节,从而产生更大的范围。

现在,如果要存储在任何变量中的值超出其范围,则它通过开始从最小范围(这里是-32568)存储的值来执行循环旋转。

你也可以使用**long long int factorial = number ;**甚至使其范围更大。由于无符号将计算其负范围与正范围,从而产生更大的正范围。

答案 4 :(得分:0)

在类或结构中尝试double或long数据类型。您还必须相应地修改您的代码。

答案 5 :(得分:0)

因素只会产生疯狂的大数字。您可以尝试使用更广泛或更宽泛的数据类型(例如long),但这只会推迟问题。它在某些时候失败。也许是51!,也许是60!。让我们甚至不谈1000!。这就是阶乘的本质。

大数字专用库当然可以大大缓解这个问题。但他们不是初学者&#39;东西。

C ++提供了一种名为std::numeric_limits的机制,它告诉您数据类型可以表示的最大可能值。

以下是基于您的代码的简单示例:

#include <iostream>
#include <limits> // needed for std::numeric_limits

using namespace std;

int main()
{
    int counter = 1;
    int number;

    cout << "Please enter a number: ";
    cin >> number;

    int factorial = number;
    while (counter != number)
    {
        if (std::numeric_limits<int>::max() / factorial < (number - counter)) {
            std::cout << "cannot handle such large numbers\n";
            return 0;
        }       
        factorial = factorial * (number - counter);
        counter++;

    }

    cout << "The factorial of " << number << "! is: " << factorial << endl;
    return 0;
}

一旦检测到错误条件,将会发生什么并不重要,而是 如何检测到它:

std::numeric_limits<int>::max() / factorial < (number - counter)

这可以防止整数溢出。它在数学上等同于:

std::numeric_limits<int>::max() < factorial * (number - counter) // wrong!

但是,后一版本显然不起作用,因为factorial * (number - counter)可能已经产生溢出。通过将右侧的乘法转换为左侧的除法,您可以优雅地避免问题。

顺便说一句,如果用户输入一个非常大的数字,所有这些仍然无益。因此,在使用std::cin之前,应检查number的状态,如果输入无法解释为int,则同样会打印错误消息。这使您的程序更加健壮。如果有人输入大数字,它不会简单地崩溃或产生无意义的结果。