1. 首页
  2. > 税务筹划 >

根号怎么计算,excel开根号怎么计算

平常我们用到的 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.41421356237309504880168872420969807856967187537694开8073176679737990732478462107038850....


可以看到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.414213562373095048801688excel72420969807856967187537694807317667973799073247846210703885038753432764157273501384623091229702492483605585073721264412149709993583141322266592750559275579995050115278206057147010955997160597027453459686201472851741864088919860955232923048430871432145083976260362799525140798968725339654633180882964062061525835239505474575028775996172983557522033753185701135437460340849884716038689997069900481503054402779031645424782306849293691862158057846311159666871301301561856898723723528850926486124949771542183342根号0428568606014682472077143585487415565706967765372022648544701585880162075847492265722600208558446652145839889394437092659180031138824646815708263010059485870400318648034219489727829064104507263688131373985525611732204024509122770022694112757362728049573810896750401836986836845072579936472906076299694138047565482372899718032680247442062926912485905218100445984215059112024944134172853147810580360337107730918286931471017111168391658172688941975871658215212822951848847

是不是感到震惊,代码竟然如此短!?


是的,没有看错,就这么一点点。


有兴趣的小伙伴可以试试 https://tool.lu/coderunner/ 的在线编译器;


左上角选择 Python 然后复制上面的代码,运行看看结果。(如下图)


按照同样的方式,大家是不是可以扩展出3次,5次.....等等的开方计算方式了?




总结

有时候思路正确了,所要做的反而就很少了!


我在心里十分佩服前人的智慧与伟大!


一起努力,加油!


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至123456@qq.com 举报,一经查实,本站将立刻删除。

联系我们

工作日:9:30-18:30,节假日休息