c++中如何求一个数的平方根_c++ sqrt函数与牛顿迭代法
技术百科
冰火之心
发布时间:2026-01-01
浏览: 次 直接用标准库sqrt函数最简单可靠,它调用CPU硬件指令,精度高、速度快、边界处理明确;牛顿迭代法仅适用于无法使用标准库或需自定义精度等特殊场景。
直接用 sqrt 函数是最简单可靠的选择
标准库的 sqrt 在 中声明,底层通常调用 CPU 的硬件指令(如 x86 的 sqrtss 或 sqrtsd),精度高、速度快、处理边界情况(如负数、NaN、无穷)有明确定义。
使用时注意:
-
sqrt重载了float、double、long double版本;传入整型会隐式转为double,但建议显式转换避免警告 - 对负数输入返回
NaN(需std::isnan检查),不抛异常 - 链接时无需额外选项,但确保编译器未禁用数学库(极少数嵌入式环境需手动链接
-lm)
double x = 16.0; double result = sqrt(x); // 得 4.0 double neg = -4.0; double bad = sqrt(neg); // bad 是 NaN,不是报错
牛顿迭代法适合理解原理或特殊约束场景
当不能用标准库(如裸机开发、教学演示、需要自定义精度/终止条件)、或需扩展到高精度浮点类型时,牛顿法是常见选择。它基于迭代公式:x_{n+1} = 0.5 * (x_n + a / x_n),从初始猜测出发逐步逼近 √a。
实操要点:
- 初始值选
a或a/2即可,但对极大/极小数,用位运算估算(如 IEEE 754 指数除以 2)能减少迭代次数 - 终止条件别只比绝对误差,用
abs(x_{n+1} - x_n) 更稳定(相对误差) - 必须处理
a == 0和a 的提前返回,否则迭代发散 - 通常 5~7 次迭代就能达到
double精度,比sqrt慢一个数量级以上
double my_sqrt(double a) {
if (a == 0.0) return 0.0;
if (a < 0.0) return std::numeric_limits::quiet_NaN();
double x = a;
double pr
ev;
do {
prev = x;
x = 0.5 * (x + a / x);
} while (abs(x - prev) youjiankuohaophpcn 1e-15 * abs(x));
return x;
}
sqrt 和牛顿法在精度与性能上的实际差异
对普通应用,sqrt 的误差通常在 0.5 ULP(unit in the last place)以内,满足 IEEE 754 要求;牛顿法若迭代不足或初始值差,可能多出 1~2 ULP,且易受舍入累积影响。
性能方面:
- 现代 x86-64 上,
sqrt 约 10–20 个周期;牛顿法单次迭代含除法(慢操作),5 次迭代常超 50 周期
- 编译器对
sqrt 可能做向量化(如 AVX-512 的 vsqrtpd),牛顿法手动向量化复杂得多
- 牛顿法唯一优势是可控——你能决定迭代次数、中间值检查、甚至换成定点运算
容易被忽略的兼容性细节
不同平台对 sqrt 的实现略有差异,但结果都在规范允许误差内。真正要小心的是:
- 某些旧编译器(如早期 MSVC)对
float sqrtf(float) 支持不全,应统一用 double 版本或加 #ifdef __cplusplus 保护
- 牛顿法中
a / x 在 x 接近 0 时可能溢出,需在循环前加 if (x 类似的防护
- 启用
-ffast-math 时,sqrt 可能被近似替换,失去 IEEE 一致性——此时牛顿法反而更可预测
除非明确知道为什么不用 sqrt,否则别自己重写。真要动手,先测边界值:0、1、DBL_MAX、DBL_MIN、负数、NaN。
# 的是
# 就能
# 都在
# 适用于
# 自定义
# 你能
# 最简单
# 迭代
# 速度快
# 循环
# c++
# if
# double
# 标准库
# 为什么
# 整型
# Float
# 浮点
# math
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- c++怎么操作redis数据库_c++ hired
- Win11怎么查看电脑配置_Win11硬件配置详细
- Win11怎么开启游戏工具栏_Windows11
- Win11怎样安装企业微信_Win11安装企业微信
- Win11怎么关闭资讯和兴趣_Windows11任
- Go 中实现 Python urllib.quot
- Windows10电脑怎么设置自动连接WiFi_W
- php订单日志怎么记录物流_php记录订单物流变更
- Win11怎么关闭应用权限_Windows11相机
- Win11怎么恢复出厂设置_Win11重置此电脑保
- Python深度学习实战教程_神经网络模型构建与训
- php修改数据怎么改富文本_update更新htm
- Mac如何彻底清理浏览器缓存?(Safari与Ch
- Python多线程使用规范_线程安全解析【教程】
- ACF 教程:如何正确更新嵌套在多层 Group
- 如何使用Golang template生成文本模板
- Win11怎么更改默认打开方式_Win11关联文件
- c++23 std::expected怎么用 c+
- Win10怎么卸载鲁大师_Win10彻底卸载鲁大师
- PHP的FastAdmin架构适合二次开发吗_特点
- Mac自带的词典App怎么用_Mac添加和使用多语
- Win10如何卸载Skype_Win10卸载Sky
- Win11怎么卸载Photos应用_Win11卸载
- Win10怎样清理C盘爱奇艺缓存_Win10清理爱
- 如何使用Golang开发基础文件下载功能_Gola
- php485支持哪些操作系统_php485跨系统支
- Mac如何整理桌面文件_Mac使用堆栈功能一键整理
- Win11开机Logo怎么换_Win11自定义启动
- Windows10系统怎么查看显卡驱动_Win10
- Windows10如何更改任务栏高度_Win10解
- 如何在 Go 中创建包含映射(map)的切片(sl
- Win11怎么设置默认图片查看器_Windows1
- php报错怎么查看_定位PHP致命错误与警告的方法
- 如何在Golang中理解指针比较_Golang地址
- 如何使用Golang log记录不同级别日志_Go
- 如何在 Django 中修改用户密码后保持会话不丢
- Win11怎么清理C盘下载文件夹_Win11清理下
- c++如何使用std::bind绑定函数参数_c+
- Win11怎么查看显卡温度 Win11任务管理器查
- PHP主流架构怎么部署到Docker_容器化流程【
- php中::能访问全局变量吗_全局作用域与类作用域
- Win11怎么关闭粘滞键_彻底禁用Windows
- Python数据抓取合法性_合规说明【指导】
- Win11怎么更改电脑名称_Windows 11修
- Windows电脑如何进入安全模式?(多种按键方法
- 如何使用Golang encoding/json解
- Win10怎样设置多显示器_Win10多显示器扩展
- mac怎么右键_MAC鼠标右键设置与触控板手势技巧
- Win11如何设置ipv6 Win11开启IPv6
- Python生成器表达式内存优化_惰性计算说明【指

ev;
do {
prev = x;
x = 0.5 * (x + a / x);
} while (abs(x - prev) youjiankuohaophpcn 1e-15 * abs(x));
return x;
QQ客服