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

时间:2015-02-01 17:36:10

标签: c++ integer-overflow

我在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;
}

3 个答案:

答案 0 :(得分:1)

当您需要操作大数字时,最好使用任意精度的算术库,例如GNU MPFR

这样,您就不必担心整数溢出。

答案 1 :(得分:1)

如果long int的尺寸与long int相同,那么int的测试将无效。要检查worknumber * 3 + 1是否以便携方式(以更快的方式)适合int,您应该测试:

workingnumber <= (INT_MAX - 1) / 3

请注意,比较的正确术语是常数,因此测试非常快。

答案 2 :(得分:0)

operetor precedence规则将c样式强制转换(long int)置于与*相同的优先级,并且从右到左具有协同性。所以首先进行乘法,然后进行投射。

尝试

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

还要注意:在某些实现中,long可能具有与int相同的精度(例如MSVC2013)。您可以使用numeric_limits轻松检查C ++编译器。如有必要,您可以选择long long int