前言:
目前看官们对“根号三c语言”可能比较关切,我们都想要学习一些“根号三c语言”的相关知识。那么小编同时在网上网罗了一些有关“根号三c语言””的相关知识,希望看官们能喜欢,各位老铁们一起来学习一下吧!序
平常我们用到的 sqrt 函数求一个数的算术平方根,以前一直好奇究竟是如何计算的。
这篇文章我们就一起来探究一下。
二分法
以前我想到的一种方式是二分法;
假设求根号2的平方根;
假设最开始 min = 1.0,max = 2.0;
则它们的中间值 val = (min+max)/2.0;
然后判断 num = val*val 的结果,
如果 num > 2;则 max = val;
如果 num < 2;则 min = val;
如果 num = 2;则 算术平方根是 val,返回。
当然有人会问,一直不等于能,当然我们可以设置计算次数;
比如执行超过 20 次后就返回,这样可以避免无线循环下去。
然而这种方法的收敛速度实在太慢,导致要计算很多次才能达到比较高的精度。
牛顿的方法
网上看到一个说是牛顿的计算方法,假设 f(x) = x^2-2;
在 x^2-2 的曲线上面,先找一个点A(X0,Y0),
过点A做曲线的切线交x轴于B(X1,0);
找到当前点B对应曲线上的点C(X1,Y1);
过点C做曲线的切线交x轴于D(X2,0);
找到当前点D对应曲线上的点E(X2,Y2);
过点E做曲线的切线交x轴于F(X3,0);
.........
按照这个过程一直下去,B D F....将会离曲线与x轴的交点越来越近,即逼近原理。
数学方法
那上面的坐标如何求取呢,对于点A,可以带入一个方便的坐标(1,-1);
由于CD是切线,点C为切点,则有如下关系:
斜率 y' = BC/BD
而:BD 可以看成是点B的x轴坐标减去点D的x轴坐标,即 BD = X1-X2;
BC 就是C点的y值,即Y1;
上面关系就变成:y' = Y1/(X1-X2)
转换一下:X1-X2 = Y1/y'
X2 = X1-Y1/y'
转换成标准的写法,则有: Xn = Xn-1 - f(Xn-1) / f '(Xn-1)
对于曲线 x^2-2 任意一点的切线可以根据多项式导数方式获取,即 f '(Xn-1) = 2x;
则有 Xn = Xn-1 - f(Xn-1) / 2x;
将A点(X0,Y0) 由曲线上的点(1,-1)带入时,
X1 = 1 - (-1/2*1) = 1.5; 此时 Y1 = 1.5^2-2 = 2.25-2 = 0.25;
X2 = 1.5 - 0.25/2*1.5 = 1.416666...667; 此时 Y1 = 0.0069444444...
以此类推
X6 = 1.4142135623730950488016887242096980785696718753772.......
对比网上查找到的根号2前100为如下:
1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850....
可以看到X6写出来的,仅仅是最后两位开始不一样。可见运算次数仅仅6次,精度已经如此高了。
代码实现
由于C/C++没找到比较稳定的高精度计算数据类,在此用Python代替了。
实现代码如下:
from decimal import Decimalfrom decimal import getcontextwork_context = getcontext()work_context.prec = 1000 // 有兴趣的可以试试更高精度num = Decimal(2) // 需要开方的数,可以试试3,5,7,11 。。。def Xn(x, y): x -= y/(x*Decimal(2)) y = x*x-num return (x,y)x = Decimal(1)y = x*x-numfor i in range(0,20): // 计算20次精度已经非常高了 x, y = Xn(x, y) print(x)第20次结果:(好像精度已经达到1000位了)1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641572735013846230912297024924836055850737212644121497099935831413222665927505592755799950501152782060571470109559971605970274534596862014728517418640889198609552329230484308714321450839762603627995251407989687253396546331808829640620615258352395054745750287759961729835575220337531857011354374603408498847160386899970699004815030544027790316454247823068492936918621580578463111596668713013015618568987237235288509264861249497715421833420428568606014682472077143585487415565706967765372022648544701585880162075847492265722600208558446652145839889394437092659180031138824646815708263010059485870400318648034219489727829064104507263688131373985525611732204024509122770022694112757362728049573810896750401836986836845072579936472906076299694138047565482372899718032680247442062926912485905218100445984215059112024944134172853147810580360337107730918286931471017111168391658172688941975871658215212822951848847
是不是感到震惊,代码竟然如此短!?
是的,没有看错,就这么一点点。
有兴趣的小伙伴可以试试 的在线编译器;
左上角选择 Python 然后复制上面的代码,运行看看结果。(如下图)
按照同样的方式,大家是不是可以扩展出3次,5次.....等等的开方计算方式了?
总结
有时候思路正确了,所要做的反而就很少了!
我在心里十分佩服前人的智慧与伟大!
一起努力,加油!
标签: #根号三c语言