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; ?>
】
相关推荐
- MAC如何快速搜索大文件_MAC磁盘空间分析与冗余
- Win11 explorer.exe频繁崩溃_修复
- Win11如何设置文件关联 Win11修改特定文件
- MAC如何设置网卡MAC地址克隆_MAC终端修改物
- Python网页解析流程_html结构说明【指导】
- Win11怎样激活系统密钥_Win11系统密钥激活
- 如何使用Golang实现微服务事件驱动_使用消息总
- php订单日志怎么记录发货_php记录订单发货操作
- Windows10如何更改任务栏高度_Win10解
- Mac如何与安卓手机传文件_Mac和Android
- 如何使用Golang读取日志文件_Golang b
- Win11更新后变慢怎么办_Win11系统更新后卡
- 如何在Golang中指定模块版本_使用go.mod
- Win11怎么关闭任务栏小组件_Windows11
- Win11视频默认播放器怎么改_Win11关联第三
- Windows10系统更新错误0x80070002
- 如何使用Golang开发基础文件下载功能_Gola
- c++协程和线程的区别 c++异步编程模型对比【核
- Win11麦克风没声音怎么设置_Win11麦克风权
- Windows10电脑怎么设置虚拟内存_Win10
- php做exe支持多线程吗_并发处理实现方式【详解
- Mac怎么给文件夹加密_Mac创建加密磁盘映像教程
- c++ namespace命名空间用法_c++避免
- c# F# 的 MailboxProcessor
- Linux如何安装Golang环境_Linux下G
- Mac怎么设置登录项_Mac管理开机自启动程序【教
- Win11怎么更改任务栏颜色_Windows11个
- Windows电脑如何截屏?(四种快捷方法)
- Win11怎么设置默认浏览器Chrome_Wind
- Mac怎么设置鼠标滚动速度_Mac鼠标设置详细参数
- Win10如何更改网络连接_Windows10以太
- Python对象比较与排序_魔术方法解析【教程】
- 新手学PHP架构总混淆概念咋办_重点梳理【教程】
- Win11怎么设置任务栏大小_Windows11注
- Mac如何查看电池健康百分比_Mac系统信息电源检
- Win11怎么清理C盘系统错误报告_Win11清理
- Windows10怎么查看硬件信息_Windows
- 如何使用Golang处理静态文件缓存_提高页面加载
- mac怎么看硬盘大小_MAC查看磁盘存储空间与文件
- 如何在Golang中处理模块包路径变化_Golan
- 如何使用Golang实现容器健康检查_监控和自动重
- 如何将文本文件中的竖排字符串转换为横排字符串
- Golang如何避免指针逃逸_Golang逃逸分析
- c++ try_emplace用法_c++ map
- Windows10电脑怎么设置虚拟光驱_Win10
- c++怎么编写动态链接库dll_c++ __dec
- windows 10专注助手怎么关闭_window
- 如何在Golang中实现并发消息队列消费者_Gol
- 如何在 Go 中创建包含 map 的 slice(
- Win11怎么关闭VBS安全性_Windows11

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