C++实现考拉兹猜想时如何正确检测数值是否超过INT_MAX
问题根因
你当前使用int类型承接用户输入,当输入值超出INT_MAX范围时,cin >> num会触发未定义行为,多数编译器实现会直接将值截断为INT_MAX,同时将cin的错误位failbit置位,你根本无法通过后续判断检测输入是否溢出。另外你原有代码里collatzCheck函数第一行的limit = (num > INT_MAX || num <= 0);是无效逻辑:num本身是int类型,取值范围不可能超过INT_MAX,这个判断永远不会触发上限条件。
可行解决方案
方案1:使用更大范围的整数类型承接输入(最简单)
直接将输入变量和计算变量替换为取值范围更大的long long类型,输入后先做范围校验,即可解决输入截断问题,同时也能覆盖更大范围的考拉兹序列计算:
#include <iostream> #include <climits> using namespace std; bool limit = false; // 函数参数改为long long int collatzCheck(long long num) { // 现在可以正常判断是否超过INT_MAX limit = (num > INT_MAX || num <= 0); if (limit) return 0; cout << "start: " << num << endl; int i = 0; while(num != 1 && !limit) { cout << ".." << endl; if(num%2 == 0) { num /= 2; } else { // 计算上限也对应调整为INT_MAX limit = (num > (INT_MAX-1)/3); if(!limit) num = num*3+1; } cout << num << endl; i++; } return i; } int main() { cout << "INT_MAX: " << INT_MAX << endl; // 输入变量改为long long long long num; cout << "num: .."; cin >> num; cout << "Iteraties: " << collatzCheck(num); if(limit) cout << ", INT_MAX is wel bereikt.." << endl; else cout << ", INT_MAX is niet bereikt!" << endl; return 0; }
方案2:开启cin输入错误校验
如果你必须使用int类型接收输入,可以在读取后判断cin的错误位,即可检测输入溢出,需要额外引入<limits>头文件:
int num; cout << "num: .."; cin >> num; // 校验输入是否合法 if (cin.fail()) { limit = true; cin.clear(); // 重置错误位 // 清空输入缓冲区剩余内容 cin.ignore(numeric_limits<streamsize>::max(), '\n'); }
方案3:先读取为字符串再转整数校验
如果需要处理的数值范围超过了long long的取值范围,可以先把用户输入读取为字符串,再手动解析字符串判断数值是否超出INT_MAX,这种方案兼容性最强但实现复杂度最高。
内容的提问来源于stack exchange,提问作者Justin Slingerland
相关产品推荐
相关产品推荐

