二分和牛顿法实现开根号

二分法:

二分的思想很直观,就不断做折半,但这里注意需要设置一个精度来替代0,由于开根号并不一定保证能够开方取尽。这里取limit = 0.00002。

牛顿法:

设r是f(x) = 0的根,选取x0作为r初始近似值,过点(x0,f(x0))做曲线y = f(x)的切线L,L的方程为y = f(x0)+f‘(x0)(x-x0),求出L与x轴交点的横坐标 x1 = x0-f(x0)/f‘(x0),称x1为r的一次近似值。

过点(x1,f(x1))做曲线y = f(x)的切线,并求该切线与x轴交点的横坐标 x2 = x1-f(x1)/f‘(x1),称x2为r的二次近似值。重复以上过程,得r的近似值序列,其中x(n+1)=x(n)-f(x(n))/f‘(x(n)),称为r的n+1次近似值,上式称为牛顿迭代公式。

根据牛顿迭代的原理,可以得到以下的迭代公式:X(n+1)=[X(n)+p/Xn]/2

https://blog.csdn.net/leviopku/article/details/82811478

代码:

 1 #include<iostream>
 2 #include<vector>
 3 #include<deque>
 4 #include<string>
 5 #define limit 0.0002
 6 using namespace std;
 7
 8 // 二分法
 9 double my_sqrt(double n)
10 {
11     double start = 0;
12     double end = n;
13     double mid = (start+end)/2;
14     while(mid*mid>n+limit || mid*mid<n-limit)
15     {
16         mid = (start+end)/2;
17         if(mid*mid>n)
18             end = mid-1;
19         else
20             start = mid+1;
21     }
22     return mid;
23 }
24
25 // 牛顿法
26 double new_sqrt(double n)
27 {
28     double k = n;
29     while(1)
30     {
31         if(k*k<n+limit && k*k>n-limit)
32         {
33             break;
34         }
35         k = 0.5*(k+n/k);
36     }
37     return k;
38 }
39 int main(){
40     double a = 81;
41     cout<<my_sqrt(a)<<endl;
42     cout<<new_sqrt(a)<<endl;
43     return 0;
44 }

原文地址:https://www.cnblogs.com/LJ-LJ/p/11221424.html

时间: 2024-11-05 18:36:29

二分和牛顿法实现开根号的相关文章

MatLab 计算开根号

对X要开根号 方法1 >> sqrt(X) 方法2 >> X^(1/2)

HDU 5828 Rikka with Sequence(线段树 开根号)

Rikka with Sequence Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2777    Accepted Submission(s): 503 Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situati

刷题向》关于线段树的区间开根号 BZOJ3211

这是一道关于线段树的区间开根号的裸题,没什么好讲的. 值得注意的是,因为有区间开根号的性质,所以我们每一次更改操作只能把更改区间所覆盖的所有元素全部查找,当然你直接找效率明显爆炸... 能够注意到,指数级别的操作一次更改的数字都很大,而题目的数字最大是10的9次,所以可以注意到的是当一个区间更新6遍以后就失去更新的意义了,因为当你更改次数超过6次所有非负整数数字就全部会化为1.所以可以在每一个节点上加一个类似于LAZY标记的东西,记录开根号次数,以便节约跟新时间. 贴出题目&代码 Descrip

H - Can you answer these queries? HDU 4027 (线段树+延迟标记+开根号的速度)

H - Can you answer these queries? Time Limit:2000MS Memory Limit:65768KB 64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4027 Description A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use our

c# 开根号 牛顿迭代

double n = 1,m;               Console.WriteLine("请输入您要开根号的数:");               m = Convert.ToDouble(Console.ReadLine());               for (int i = 0; 1==1; i++)               {                   n = (n + m / n) /2;                               

hdu 4027 Can you answer these queries? 线段树区间开根号,区间求和

Can you answer these queries? Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5195 Description A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use our secret weapo

神奇的开根号模板

在codevs里发现的一份高精度开根号模板. int l,last; int work(int o,char *O,int I) { char c,*D=O; if(o>0) { for(l=0;D[l];D[l++]-=10) { D[l++]-=120; D[l]-=110; while(!work(0,O,l)) D[l]+=20; last=((D[l]+1032)/20); } //putchar(10); } else { c=o+(D[I]+82)%10-(I>l/2)*(D[I

luogu P4145 上帝造题的七分钟2 / 花神游历各国 维护区间和&amp;&amp;区间开根号

因为开根号能使数字减小得非常快 所以开不了几次(6次?)很大的数就会变成1..... 所以我们可以维护区间最大值,若最大值>1,则继续递归子树,暴力修改叶节点,否则直接return (好像也可以维护区间被开方的次数,但我不会...QAQ) #include<cstdio> #include<iostream> #include<cmath> #define int long long #define R register int #define ls (tr<

开根号(二分法、牛顿法)

二分法开根号,通过二分法在[0,n]之间寻找合适的数(n>1时),而n<1时,需要将上限设为1,即使用二分法在[0,1]之间寻找合适的数,最终达到一定精度跳出循环,但迭代很慢. 牛顿法可以快速迭代(牛顿法介绍) 原文地址:https://www.cnblogs.com/zwtgyh/p/11470123.html