/* 头部 */ #header { position: relative; height: 280px; margin: 0; background: #020031; background: -moz-linear-gradient(45deg,#020031 0,#6d3353 100%); background: -webkit-gradient(linear,left bottom,right top,color-stop(0%,#020031),color-stop(100%,#6d3353)); background: -webkit-linear-gradient(45deg,#020031 0,#6d3353 100%); background: -o-linear-gradient(45deg,#020031 0,#6d3353 100%); background: -ms-linear-gradient(45deg,#020031 0,#6d3353 100%); background: linear-gradient(45deg,#020031 0,#6d3353 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#020031', endColorstr='#6d3353', GradientType=1); -webkit-box-shadow: inset 0 3px 7px rgba(0,0,0,.2),inset 0 -3px 7px rgba(0,0,0,.2); -moz-box-shadow: inset 0 3px 7px rgba(0,0,0,.2),inset 0 -3px 7px rgba(0,0,0,.2); box-shadow: inset 0 3px 7px rgba(0,0,0,.2),inset 0 -3px 7px rgba(0,0,0,.2); }

四则运算开平方——对民科吧编程大赛题目的再探究

题目传送地址:https://tieba.baidu.com/p/6809881927

规则大意:
仅仅使用加减乘除四则运算进行任意正数的算数平方根运算
可以多次迭代
精度要求到小数点后的6位

解答部分:

前言:

几乎是很迅速地,我能想到四种方法(这四种方法都是高等数学书上列出的):

二分迭代法,牛顿迭代法,拟牛顿迭代法,弦截迭代法。

经过深入思考以后我想到了另外两种速度比较快的算法:

导数迭代法,向量趋近迭代法(自己想的瞎起的名)。

 2020.7.22 今天先写一下导数迭代法。

导数迭代法:

求一个方程 f(x)=a 的解。

由导数的定义可知,如果把 x 加上一个很小的值 Δx0,那么f(x+Δx)就变成了f(x)+f(x)Δx

由此我们可以先求出f(x)的一个近似解 x0作为初始迭代值。每次增加Δx=(f(xi)a)f(xi)

因为Δx 的值很小,每迭代一次就会离最终结果更近一点。经过反复迭代以后就可以达到足够的精度。

此方法对于任意平滑函数求解方程的根都可适用。

归纳步骤:

对一个数 a 求平方根,就是求 a12 的值。

f(x)=x,则f(x)=12x

我们可以先求出f(x)=a的一个近似解,可以选择a的数量级的一半(语文不好,即 x0=10lg(a)2作为初始迭代值。

可以发现f(x)中仍然出现了开方。由于我们无法使用开平方函数,所以在计算过程中不能使用普通的导数迭代法,要重新构建模型:

我们可以确定的是1=1,那么为什么不用1作为函数的近似解呢?

不要以为我在异想天开!将x=1带人以后就可以得到:

 

limΔx01+Δx=1+x2

我们假设已经求出来了方程f(x)=a的一个近似解x0,那么就有:

a=x02+Δx

提出来一个x0以后就变成了:

a=x01+Δxx02

很成功地,我们得到了下一个迭代近似解x1

x1=x0(1+Δx2x02)

即:

x1=x0+Δx2x0

来进行下一次迭代。

 

代码实现:

由于博主水平有限,到目前为止只会 C++ (倒是学过一点 Python 但是现在都忘了),抱歉只能写一个残废的代码(不支持高精度,卡不卡炸不炸只能看您的数据和电脑配置)。

 

复制代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 long double a,b,c; 4 int w,ite,i=1; 5 int get_lg(int m){ 6 while(m)w++,m/=10; 7 return w; 8 } 9 int get_first_ite(int m){ 10 while(m)m--,i*=10; 11 return i; 12 } 13 int main(){ 14 cin>>a; 15 b=get_first_ite(get_lg(a)/2); 16 while(abs(b*b-a)>1e-6){ 17 ite++; 18 c=b*b-a; 19 b-=(c/(2*b)); 20 cout<<"iterate time="<<ite<<" b="<<b<<" error="<<abs(b*b-a)<<endl; 21 } 22 cout<<fixed<<setprecision(6)<<b<<endl; 23 }
复制代码

 

可以发现此方法的迭代次数还是很少的


__EOF__

本文作者小红
本文链接https://www.cnblogs.com/little-red/p/Iterate_sqrt.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   是小红吖  阅读(722)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示