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