2022年 11月 9日

python 实现开方

问题描述:利用python实现开根号操作

1.调用库的方法

  1. import math
  2. res = math.sqrt(x)

或者一个python特性的方法

res = x ** 0.5

2.二分法实现

二分法实现要主要x的范围,对应的二分范围也不同:

0\leqslant x\leqslant 1时,二分的范围应该是\left [ 0,x+1/4 \right ],这个可以求导得到

x> 1时,范围应该是\left [ 1, x \right /2]

二分法应该给定一个精度,每次二分的结果平方和x比较,如果小于精度,则返回

  1. import math
  2. def sqrt_binary(num, p):
  3. """
  4. num为待开方数字
  5. p为给定的精度,例如1e-5
  6. """
  7. if num < 0:
  8. return None
  9. elif num > 1:
  10. l = 1
  11. r = num/2
  12. else:
  13. l = 0
  14. r = num + 0.25
  15. while l < r:
  16. mid = (l + r) / 2
  17. curnum = mid ** 2
  18. if abs(curnum - num) <= p:
  19. return mid
  20. elif curnum < num:
  21. l = mid
  22. else:
  23. r = mid
  24. num = 100
  25. print(sqrt_binary(num, 1e-06), math.sqrt(num))

3.牛顿法

问题可以等效与求解f(x)=x^{^{2}}-num的零点

泰勒一阶展开:f(x)=f(x_{0})+f^{'}(x_{0})(x-x_{0})

令f(x)=0,有x=x_{0}-f(x_{0})/f^{'}(x_{0})

对于f(x),导数为2x,求得:x=\frac{1}{2}(x_{0} + \frac{n}{x_{0}})

每次按照上面的公式更新x即可

  1. def sqrt_newton(num, p):
  2. """
  3. num为待开方数字
  4. p为给定的精度,例如1e-5
  5. """
  6. if num == 0:
  7. return 0
  8. x = num / 2
  9. while abs(x ** 2 - num) > p:
  10. x = (x + num / x) / 2
  11. return x
  12. num = 0.16
  13. p = 1e-5
  14. print(sqrt_newton(num, p))