C++中sqrt()函数判断完全平方数的问题求助
问题原因
你的代码依赖sqrt()浮点数函数,而浮点数的二进制表示存在精度限制。哪怕是小的完全平方数,sqrt(t)返回的结果也可能因为精度问题略小于实际整数(比如sqrt(25)可能返回4.999999999999999),强制转成int后会截断小数部分得到4,此时4*4=16≠25,导致误判。不同平台/编译器的浮点数实现细节有差异,这就是本地运行正确但在线评测失败的原因。
跨平台通用的完全平方数判断方法
方法1:修正浮点数精度误差问题
在计算整数平方根后,同时检查当前值和下一个整数的平方是否等于原数,覆盖精度偏差的情况:
#include <cmath> #include <iostream> using namespace std; bool isPerfectSquare(int t) { if (t < 0) return false; // 负数不可能是完全平方数 long long sqrt_t = static_cast<long long>(sqrt(t)); // 检查当前平方根和+1后的平方,避免精度截断问题 return sqrt_t * sqrt_t == t || (sqrt_t + 1) * (sqrt_t + 1) == t; }
方法2:二分查找法(推荐,无浮点数依赖)
完全使用整数运算,通过二分查找找到是否存在整数mid使得mid*mid == t,彻底避免浮点数精度问题,跨平台一致性最高:
#include <iostream> using namespace std; bool isPerfectSquare(int t) { if (t < 0) return false; long long left = 0, right = static_cast<long long>(t); while (left <= right) { long long mid = left + (right - left) / 2; // 避免溢出的写法 long long square = mid * mid; if (square == t) { return true; } else if (square < t) { left = mid + 1; } else { right = mid - 1; } } return false; }
注:使用long long是为了避免计算平方时的溢出问题,即使输入是int类型的最大值,mid*mid也不会超出long long的范围。
内容的提问来源于stack exchange,提问作者Vedanta Mohapatra
相关产品推荐
相关产品推荐

