检查计算是否会导致溢出c++

Checking if calculation will cause overflow c++

我在 collat​​z() 中添加了 elseif 语句来检查 workingnumber * 3 + 1 是否会超过 INT_MAX 但是当 运行 程序有些数字不应该超过 INT_MAX 据报道这样做。我可能不需要施法 INT_MAX 但我不确定。

#include <iostream>
#include <cstdlib>
#include <climits>

using namespace std;

void collatz( int startingnumber ) {

    int count = 0;

    int originalnumber = startingnumber;

    int workingnumber = startingnumber;

    while( workingnumber >= 1 ) {

        if( workingnumber == 1 ) {

            cout << originalnumber << " takes " << count << " steps" << endl;

            count = 0;

            break;
        }

        if( workingnumber % 2 == 0 ) {

            workingnumber /= 2;

            //optional
            //cout << originalnumber << " is at " << workingnumber << endl;

            count++;
        }
        else if( ( ( long int ) workingnumber * 3 ) + 1 > ( long int ) INT_MAX ) {

            cout << originalnumber << " will cause a buffer overflow" << endl;

            break;
        }        
        else {

            workingnumber = ( 3 * workingnumber ) + 1;

            //optional
            //cout << originalnumber << " is at " << workingnumber << endl;

            count++;
        }
    }
}

int main( int argc, char* argv[] ) {

    int increment = 2;

    if( argc > 1 ) {

        if( atoi( argv[1] ) != 0 ) {

            increment = atoi( argv[1] );
        }
    }

    while( increment <= INT_MAX ) {

        collatz( increment );

        increment++;
    }

    return 0;
}

operetor precedence 规则将 c 风格的类型转换(long int)置于与 * 相同的优先级并且从右到左具有关联性。所以首先完成乘法,然后进行转换。

尝试

else if( ( (( long int ) workingnumber) * 3 ) + 1 > INT_MAX )

另请注意:在某些实现中,long 可能与 int 具有相同的精度(例如 MSVC2013). You can easily check for your C++ compiler by using numeric_limits。您可以选择 long long int 如有必要。

当您需要对大数进行运算时,最好使用任意精度的算术库,例如GNU MPFR

这样就不用担心整数溢出了。

如果 long int 的大小与 int 的大小相同,则您使用 long int 的测试将不起作用。要检查 workingnumber * 3 + 1 是否适合 int 以可移植的方式(并且以更快的方式),您应该测试:

workingnumber <= (INT_MAX - 1) / 3

注意比较的右项是常数,这样测试很快