如题,先看看书上给出的示例代码:
#<程序:平方根运算2-二分法>
def square_root_2():
i=0
c=10 #书上以10为例
m_max=c
m_min=0
g=(m_min + m_max)/2
while(abs(g*g-c)>0.00000000001): #while循环开始
if(g*g<c):
m_min=g
else:
m_max=g
g=(m_min+m_max)/2
i=i+1
print("%d:%.13f"%(i,g)) #while循环结束
#函数之外执行
square_root_2()
但是,这个代码却存在着不足:
- 只能运算大于1的数的平方根,而对于大于0且小于1的却无能为力。
- 若按c介于0到1直接修改代码并添加,则在该精度下计算得的数值误差较大,需要调整精度。
- 对于0无法输出正确值。
下面,给出优化过的代码(当然,水平不足,代码冗长):
#<程序:平方根运算-二分法>
def square_root():
i=0 #循环次数i
c=float(input()) #从键盘读取输入被开方数c
if(c<0):
print("Error")
elif(c==0):
print(0)
elif(c>=1):
Max=c
Min=1
g=(Max+Min)/2
Accuracy=0.000000000000001 #设定精度
while(abs(g*g-c)>Accuracy):
if(g*g-c>0):
Max=g
else:
Min=g
g=(Max+Min)/2
i=i+1
print("%d,%.13f",(i,g))
else:
Max=1
Min=c
g=(Max+Min)/2
Accuracy=0.0000000000000000000001
#import numpy
#j=numpy.log10(c)
#while(j%2==0):
# Accuracy=Accuracy*0.01
# j=j/2
while(abs(g*g-c)>Accuracy):
if(g*g-c>0):
Max=g
else:
Min=g
g=(Max+Min)/2
i=i+1
print("%d,%.13f",(i,g))
if(g%0.1==0): #将出现死循环
break #跳出循环
square_root()
大家可能注意到了,中间有一段代码被标记为注释,运用numpy库取对数进而调整精度。
起因是用该程序计算10^(-8)时仍然存在一定误差:
如果使用了numpy库,结果则更加精确(但时间稍长):
但是,这个程序依然存在问题:
- 对于更小的数,诸如10^(-10),却又存在误差:
- 语句
j=numpy.log10(c)
无法得到诸如2*10^(-10)的数的正确答案。
由于水平不足,本人目前无法解决该问题,还望大佬指教。
不过,如果换为用牛顿法实现,就能够通杀上述问题了:
#<程序:平方根运算-牛顿法>
def Newton_sqrt():
c=float(input())
g=c/2
i=0
Accuracy=0.00000000000001
while(abs(g*g-c)>Accuracy):
g=(g+c/g)/2
i=i+1
print("%d,%.13f"%(i,g))
Newton_sqrt()
欢迎大佬们赐教!