检查计算是否会导致溢出c++
Checking if calculation will cause overflow c++
我在 collatz() 中添加了 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
注意比较的右项是常数,这样测试很快
我在 collatz() 中添加了 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
注意比较的右项是常数,这样测试很快