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; ?>
】
相关推荐
- Win11怎么关闭搜索历史_Win11清除设备上的
- 如何用::实现工具类方法调用_php静态工具类设计
- Golang如何测试HTTP中间件_Golang
- Windows10如何更改计算机工作组_Win10
- php转mp4怎么保留字幕_php处理带字幕视频转
- Win11怎么关闭自动调节亮度_Windows11
- php怎么操作Redis_Redis扩展连接与基本
- 如何在 Django 中安全修改用户密码而不使会话
- Python代码测试策略_质量保障解析【教程】
- 如何在Golang中实现WebSocket广播_使
- Win11相机打不开提示错误怎么修_相机权限开启与
- 如何使用Golang进行HTTP服务性能测试_测量
- Python技术债务管理_长期维护解析【教程】
- c++23 std::expected怎么用 c+
- Python对象比较与排序_魔术方法解析【教程】
- PHP 中如何在函数内持久修改引用变量所指向的目标
- Bpmn 2.0的XML文件怎么画流程图
- 手机php文件怎么变成mp4_安卓苹果打开php转
- XSLT怎么生成动态的HTML属性名和标签名
- MAC怎么一键隐藏桌面所有图标_MAC极简模式切换
- mac怎么分屏_MAC双屏显示与分屏操作技巧【指南
- VSC怎样在Linux运行PHP_Ubuntu系统
- Windows10如何彻底关闭自动更新_Win10
- 如何使用Golang构建基础消息队列模拟_Gola
- Windows10系统怎么查看IP地址_Win10
- Windows10如何更改盘符名称_Win10重命
- Win11怎么关闭开机声音_Win11系统启动提示
- 如何在JavaScript中动态拼接PHP的bas
- Win11怎么修复系统文件_使用sfc命令修复Wi
- Win11怎么关闭自动维护 Win11禁用系统自动
- Python数据挖掘进阶教程_分类回归与聚类案例解
- Windows10电脑怎么设置防火墙出站规则_Wi
- Win11怎么开启上帝模式_创建Windows 1
- Win11怎么开启剪贴板历史记录_Windows1
- 如何在 Go 项目开发中正确处理本地包导入与远程模
- Win11怎么设置开机问候语_自定义Win11锁屏
- php文件怎么变mp4保存_php输出视频流保存为
- Win11如何设置开机问候语 Win11修改登录界
- 如何使用Golang指针与接口结合_实现方法调用和
- 一文详解网站被黑客入侵挂马解决办法
- Win11怎么开启HDR模式_Windows 11
- php查询数据怎么分组_groupby分组查询配合
- Win11怎么设置虚拟键盘_打开Win11屏幕键盘
- Win11怎么更改输入法顺序_Win11调整语言首
- Win11系统占用空间大怎么办 Win11深度瘦身
- Win11怎么清理C盘下载文件夹_Win11清理下
- 如何在 Pandas 中按元素交集合并两列字符串
- c++中如何使用std::variant_c++1
- Mac电脑进水了怎么办_MacBook进水后紧急处
- Win11怎么更改系统语言为中文_Windows1

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