我是C++编程的新手,并且编写了一个简单的程序来计算用户提供的整数的阶乘。我正在尝试考虑可能导致错误或没有意义的输入(例如,我已经考虑了负数/ -1的输入)。如果用户输入一个其阶乘将大于最大整数大小的数字,我想打印一个错误。

我开始于:

if(factorial(n) > INT_MAX)
std::cout << "nope";
continue

我用n =〜25或26进行了测试,但这并不能防止结果溢出并打印出较大的负数。

其次,我尝试使用'limits.h' header 中的函数将其分配给变量,然后将factorial(n)的结果与此进行比较。还是没有运气(您可以在下面的代码示例中看到此解决方案)。

我当然可以将结果分配给long并对此进行测试,但是您也不必走太远,直到您开始包装该值。如果发生这种情况,我希望找到一种方法来简单地防止打印该值。
#include <iostream>
#include <cstdlib>
#include <limits>

int factorial(int n)
{
    auto total = 1;

    for(auto i = 1; i <= n; i++)
    {
        total = total * i;      //Product of all numbers up to n
    }
    return total;
}

int main()
{
    auto input_toggle = true;
    auto n = 0;
    auto int_max_size = std::numeric_limits<int>::max();

    while(input_toggle = true)
    {
    /* get user input, check it is an integer */
            if (factorial(n) > int_max_size)
        {
            std::cout << "Error - Sorry, factorial of " << n << " is larger than \nthe maximum integer size supported by this system. " << std::endl;
            continue;
        }

        /* else std::cout << factorial(n) << std::endl; */`

与我的其他情况一样,我希望它只是打印出该小错误消息,然后继续要求用户输入要计算的内容。该代码可以正常工作,如果我请求值> 25左右的阶乘,它只会继续打印缠绕的值。我觉得这种错误检查将非常有用。

谢谢!

最佳答案

您正在尝试倒退。

首先,根据定义,没有一个整数实际上可以大于INT_MAX,这是整数可以达到的最大值!因此,您的条件factorial(n) > int_max_size始终为假。

而且,您的方法存在逻辑缺陷。首先计算该值,然后检查该值是否小于允许的最大值。到那个时候已经为时已晚!您已经计算出该值并经历了可能遇到的所有溢出。您可能正在执行的所有检查都应在仍在进行计算时执行。

本质上,您需要检查XZ的乘积是否在允许范围内而无需实际进行乘法操作(不幸的是,C++非常严格地保留有符号整数溢出未定义的行为,因此您无法尝试看看。)

那么,如何检查X * Y是否小于Z?一种方法是在进行计算之前将Z除以Y。如果最后得到的数字小于X,那么您知道XY相乘会导致溢出。

我相信,您知道有足够的信息可以自己编写解决方案。

关于c++ - 防止用户输入将导致整数溢出的值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57913917/

10-11 23:15
查看更多