根号2的程序计算方法(Python)(算法 根号2)
wptr33 2025-06-23 22:40 15 浏览
序
平常我们用到的 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 Decimal
from decimal import getcontext
work_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-num
for i in range(0,20): // 计算20次精度已经非常高了
x, y = Xn(x, y)
print(x)
第20次结果:(好像精度已经达到1000位了)
1.414213562373095048801688724209698078569671875376948073176679737990732478462
10703885038753432764157273501384623091229702492483605585073721264412149709993
58314132226659275055927557999505011527820605714701095599716059702745345968620
14728517418640889198609552329230484308714321450839762603627995251407989687253
39654633180882964062061525835239505474575028775996172983557522033753185701135
43746034084988471603868999706990048150305440277903164542478230684929369186215
80578463111596668713013015618568987237235288509264861249497715421833420428568
60601468247207714358548741556570696776537202264854470158588016207584749226572
26002085584466521458398893944370926591800311388246468157082630100594858704003
18648034219489727829064104507263688131373985525611732204024509122770022694112
75736272804957381089675040183698683684507257993647290607629969413804756548237
28997180326802474420629269124859052181004459842150591120249441341728531478105
80360337107730918286931471017111168391658172688941975871658215212822951848847
是不是感到震惊,代码竟然如此短!?
是的,没有看错,就这么一点点。
有兴趣的小伙伴可以试试
https://tool.lu/coderunner/ 的在线编译器;
左上角选择 Python 然后复制上面的代码,运行看看结果。(如下图)
按照同样的方式,大家是不是可以扩展出3次,5次.....等等的开方计算方式了?
总结
有时候思路正确了,所要做的反而就很少了!
我在心里十分佩服前人的智慧与伟大!
一起努力,加油!
相关推荐
- MySQL进阶五之自动读写分离mysql-proxy
-
自动读写分离目前,大量现网用户的业务场景中存在读多写少、业务负载无法预测等情况,在有大量读请求的应用场景下,单个实例可能无法承受读取压力,甚至会对业务产生影响。为了实现读取能力的弹性扩展,分担数据库压...
- 3分钟短文 | Laravel SQL筛选两个日期之间的记录,怎么写?
-
引言今天说一个细分的需求,在模型中,或者使用laravel提供的EloquentORM功能,构造查询语句时,返回位于两个指定的日期之间的条目。应该怎么写?本文通过几个例子,为大家梳理一下。学习时...
- 一文由浅入深带你完全掌握MySQL的锁机制原理与应用
-
本文将跟大家聊聊InnoDB的锁。本文比较长,包括一条SQL是如何加锁的,一些加锁规则、如何分析和解决死锁问题等内容,建议耐心读完,肯定对大家有帮助的。为什么需要加锁呢?...
- 验证Mysql中联合索引的最左匹配原则
-
后端面试中一定是必问mysql的,在以往的面试中好几个面试官都反馈我Mysql基础不行,今天来着重复习一下自己的弱点知识。在Mysql调优中索引优化又是非常重要的方法,不管公司的大小只要后端项目中用到...
- MySQL索引解析(联合索引/最左前缀/覆盖索引/索引下推)
-
目录1.索引基础...
- 你会看 MySQL 的执行计划(EXPLAIN)吗?
-
SQL执行太慢怎么办?我们通常会使用EXPLAIN命令来查看SQL的执行计划,然后根据执行计划找出问题所在并进行优化。用法简介...
- MySQL 从入门到精通(四)之索引结构
-
索引概述索引(index),是帮助MySQL高效获取数据的数据结构(有序),在数据之外,数据库系统还维护者满足特定查询算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构...
- mysql总结——面试中最常问到的知识点
-
mysql作为开源数据库中的榜一大哥,一直是面试官们考察的重中之重。今天,我们来总结一下mysql的知识点,供大家复习参照,看完这些知识点,再加上一些边角细节,基本上能够应付大多mysql相关面试了(...
- mysql总结——面试中最常问到的知识点(2)
-
首先我们回顾一下上篇内容,主要复习了索引,事务,锁,以及SQL优化的工具。本篇文章接着写后面的内容。性能优化索引优化,SQL中索引的相关优化主要有以下几个方面:最好是全匹配。如果是联合索引的话,遵循最...
- MySQL基础全知全解!超详细无废话!轻松上手~
-
本期内容提醒:全篇2300+字,篇幅较长,可搭配饭菜一同“食”用,全篇无废话(除了这句),干货满满,可收藏供后期反复观看。注:MySQL中语法不区分大小写,本篇中...
- 深入剖析 MySQL 中的锁机制原理_mysql 锁详解
-
在互联网软件开发领域,MySQL作为一款广泛应用的关系型数据库管理系统,其锁机制在保障数据一致性和实现并发控制方面扮演着举足轻重的角色。对于互联网软件开发人员而言,深入理解MySQL的锁机制原理...
- Java 与 MySQL 性能优化:MySQL分区表设计与性能优化全解析
-
引言在数据库管理领域,随着数据量的不断增长,如何高效地管理和操作数据成为了一个关键问题。MySQL分区表作为一种有效的数据管理技术,能够将大型表划分为多个更小、更易管理的分区,从而提升数据库的性能和可...
- MySQL基础篇:DQL数据查询操作_mysql 查
-
一、基础查询DQL基础查询语法SELECT字段列表FROM表名列表WHERE条件列表GROUPBY分组字段列表HAVING分组后条件列表ORDERBY排序字段列表LIMIT...
- MySql:索引的基本使用_mysql索引的使用和原理
-
一、索引基础概念1.什么是索引?索引是数据库表的特殊数据结构(通常是B+树),用于...
- 一周热门
-
-
C# 13 和 .NET 9 全知道 :13 使用 ASP.NET Core 构建网站 (1)
-
程序员的开源月刊《HelloGitHub》第 71 期
-
详细介绍一下Redis的Watch机制,可以利用Watch机制来做什么?
-
假如有100W个用户抢一张票,除了负载均衡办法,怎么支持高并发?
-
Java面试必考问题:什么是乐观锁与悲观锁
-
如何将AI助手接入微信(打开ai手机助手)
-
redission YYDS spring boot redission 使用
-
SparkSQL——DataFrame的创建与使用
-
一文带你了解Redis与Memcached? redis与memcached的区别
-
如何利用Redis进行事务处理呢? 如何利用redis进行事务处理呢英文
-
- 最近发表
- 标签列表
-
- git pull (33)
- git fetch (35)
- mysql insert (35)
- mysql distinct (37)
- concat_ws (36)
- java continue (36)
- jenkins官网 (37)
- mysql 子查询 (37)
- python元组 (33)
- mybatis 分页 (35)
- vba split (37)
- redis watch (34)
- python list sort (37)
- nvarchar2 (34)
- mysql not null (36)
- hmset (35)
- python telnet (35)
- python readlines() 方法 (36)
- munmap (35)
- docker network create (35)
- redis 集合 (37)
- python sftp (37)
- setpriority (34)
- c语言 switch (34)
- git commit (34)