防止用户输入会导致整数溢出的值

Prevent a user from entering a value which would cause integer to overflow

我是 C++ 编程的新手,编写了一个简单的程序来计算用户提供的整数的阶乘。我正在尝试考虑会导致错误或没有意义的输入(例如,我已经考虑了负 number/-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 左右的阶乘,它只会继续打印已环绕的值。我觉得这种error-checking会很有用

谢谢!

您正在尝试倒退。

首先,实际上没有整数可以大于INT_MAX,根据定义——这是一个整数可以的最大值!所以你的条件 factorial(n) > int_max_size 永远是假的。

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

本质上,您需要检查 X 乘以 Z 是否在允许的范围内而不实际执行乘法(不幸的是,C++ 非常严格地保留有符号整数溢出未定义的行为,所以你不能试试看。)。

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

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