C++ 怎么判断完全平方数 C++ sqrt取整判断逻辑【算法】

发布时间 - 2026-01-30 00:00:00    点击率:
直接比较sqrt(n)与取整值易错,因double精度不足(仅精确到2^53≈9e15),大数如9999999999999999会误判;正确做法是取整后检查r−1、r、r+1三个候选值平方是否等于n。

sqrt 判断完全平方数,为什么直接比较 sqrt(n) 和它的取整值容易出错?

因为 sqrt 返回 double,浮点数精度在大整数(比如接近 LLONG_MAX)时无法精确表示整数,static_cast(sqrt(n)) 可能向下舍入一格。例如 n = 9999999999999999sqrt 计算结果可能是 99999999.99999999,强制转 long long 后变成 99999999,平方后远小于原数,但实际它本就是完全平方数(100000000²)。

正确做法是:取整后向上、向下各试一个候选值,再平方比对:

long long r = static_cast(std::sqrt(n));
for (long long x : {r - 1, r, r + 1}) {
    if (x >= 0 && x * x == n) return true;
}
return false;

std::sqrt 的参数类型和溢出风险必须手动控制

std::sqrtint 会隐式转成 double,而 double 能精确表示的整数上限约是 2^53 ≈ 9e15。一旦 n > 9e15sqrt(n) 的输入就已失真,后续判断必然不可靠。

  • long long 类型输入,先做范围检查:if (n > 9007199254740992LL) {...}
  • 更稳妥的方式是避免 sqrt:用二分查找在 [0, n][0, min(n, 1LL 内找平方根(n 很大时上界可设为 sqrt(LLONG_MAX)3e9
  • 注意 x * x 可能溢出,比较前应加 if (x > 0 && n / x 做除法防溢出

使用 std::sqrt 前必须包含头文件并处理负数

std::sqrt 中声明,不包含会编译失败或触发隐式声明警告。且 sqrt 对负数返回 NaNstatic_cast 后行为未定义 —— 必须先判负:

#include

... if (n < 0) return false; long long r = static_cast(std::sqrt(n));

另外,std::sqrt 有多个重载,传 int 调用的是 double sqrt(double),不是 float 版,这点无需额外指定,但不能依赖 sqrtf

整数二分法判断完全平方数更安全、无精度问题

当需要 100% 正确性(尤其处理大整数或写库函数时),放弃 sqrt 是最干净的选择。核心逻辑是找满足 x² ≤ n 的最大 x,再验证 x² == n

if (n < 0) return false;
long long lo = 0, hi = n;
while (lo <= hi) {
    long long mid = lo + (hi - lo) / 2;
    if (mid > 3037000499LL) { hi = mid - 1; continue; } // 防 mid*mid 溢出
    long long sq = mid * mid;
    if (sq == n) return true;
    if (sq < n) lo = mid + 1;
    else hi = mid - 1;
}
return false;

3037000499LLsqrt(LLONG_MAX) 的下取整,超过它平方必溢出。这个边界值比每次做除法判断更高效,也更直观。

浮点 sqrt 看似简单,但边界 case 太多;整数二分写一次,后面所有输入都稳。真正上线或做算法题时,别省那几行代码。


# c++  # 为什么  # if  # int  # double  # 算法  # 的是  # 太多  # 隐式  # 多个  # 浮点  # 设为  # 必须先  # 转成  # 也更  # 比对 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 原生JS获取元素集合的子元素宽度实例  高性能网站服务器配置指南:安全稳定与高效建站核心方案  网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?  深入理解Android中的xmlns:tools属性  如何用y主机助手快速搭建网站?  家族网站制作贴纸教程视频,用豆子做粘帖画怎么制作?  Laravel 419 page expired怎么解决_Laravel CSRF令牌过期处理  Laravel中的Facade(门面)到底是什么原理  Laravel项目如何进行性能优化_Laravel应用性能分析与优化技巧大全  浅谈javascript alert和confirm的美化  如何在云主机上快速搭建多站点网站?  js实现获取鼠标当前的位置  邀请函制作网站有哪些,有没有做年会邀请函的网站啊?在线制作,模板很多的那种?  Laravel如何编写单元测试和功能测试?(PHPUnit示例)  JavaScript如何操作视频_媒体API怎么控制播放  Claude怎样写结构化提示词_Claude结构化提示词写法【教程】  Thinkphp 中 distinct 的用法解析  php打包exe后无法访问网络共享_共享权限设置方法【教程】  Laravel怎么实现验证码(Captcha)功能  打开php文件提示内存不足_怎么调整php内存限制【解决方案】  Python文本处理实践_日志清洗解析【指导】  再谈Python中的字符串与字符编码(推荐)  PHP正则匹配日期和时间(时间戳转换)的实例代码  如何在企业微信快速生成手机电脑官网?  Laravel策略(Policy)如何控制权限_Laravel Gates与Policies实现用户授权  如何实现javascript表单验证_正则表达式有哪些实用技巧  jQuery中的100个技巧汇总  Gemini手机端怎么发图片_Gemini手机端发图方法【步骤】  三星网站视频制作教程下载,三星w23网页如何全屏?  JavaScript如何实现音频处理_Web Audio API如何工作?  微信小程序 scroll-view组件实现列表页实例代码  网站制作大概要多少钱一个,做一个平台网站大概多少钱?  网站建设整体流程解析,建站其实很容易!  Laravel如何使用.env文件管理环境变量?(最佳实践)  Gemini怎么用新功能实时问答_Gemini实时问答使用【步骤】  Laravel Debugbar怎么安装_Laravel调试工具栏配置指南  php json中文编码为null的解决办法  Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践  html5怎么画眼睛_HT5用Canvas或SVG画眼球瞳孔加JS控制动态【绘制】  使用C语言编写圣诞表白程序  如何在沈阳梯子盘古建站优化SEO排名与功能模块?  Laravel storage目录权限问题_Laravel文件写入权限设置  阿里云高弹*务器配置方案|支持分布式架构与多节点部署  Python结构化数据采集_字段抽取解析【教程】  Laravel如何操作JSON类型的数据库字段?(Eloquent示例)  Android中Textview和图片同行显示(文字超出用省略号,图片自动靠右边)  IOS倒计时设置UIButton标题title的抖动问题  Laravel如何创建自定义Artisan命令?(代码示例)  HTML透明颜色代码在Angular里怎么设置_Angular透明颜色使用指南【详解】  Laravel如何使用Gate和Policy进行授权?(权限控制)