我正在尝试使用牛顿算法对某个数字的平方根进行近似编程,但是当它为根数为整数的数字进行编程时,它只会因其他所有内容而失败。每次我尝试计算2.25或3或更高的平方时,我都会遇到运行时错误。我该如何解决这个问题?
n = float(input("Which number's square root would you want to compute? "))
def oldguess():
root = n /2
return root
def newguess():
root = 0.5 * (oldguess() + n / oldguess())
if root**2 == n:
print root
return root
else:
newguess()
newguess()
答案 0 :(得分:0)
因为浮点数如何工作1.23 ** 2永远不会等于你想要的......你需要检查一个阈值
threshold = 1e-5
if abs(root**2 - n) < threshold :
但这似乎不是牛顿法...这是你应该如何根据http://en.wikipedia.org/wiki/Newton%27s_method#Square_root_of_a_number实现它
实际上你应该将先前的猜测与当前的猜测(或当前的猜测)进行比较......因为它总是收敛到一个解决方案,它会在每次迭代时继续接近解决方案(快速,即先前猜测和之间的差异)当前的猜测会迅速接近零)....
所以我会像这样实现它
import random
def newton_squareroot(target,guess=None):
if guess is None:
guess = random.randint(1,int(target))
threshold = 1e-5
next_guess = guess - (guess**2-target)/float(2*guess)
if abs(guess-next_guess)< threshold:
return next_guess
return newton_squareroot( target,next_guess)
print newton_squareroot(2.5)
答案 1 :(得分:0)
@ Joran-Beasly建议,不要使用硬编码阈值,最好保持循环,直到近似值无法改善。
答案 2 :(得分:0)
你的方法实际上不是递归,递归意味着你在一个方法中调用相同的方法并且重用它的结果,或者传递属性以便下次调用适用于前一个。在你的方法中:
def newguess():
root = 0.5 * (oldguess() + n / oldguess()) #oldguess remains the same, so nothing incremental, every guess will be as bad as the previous one
if root**2 == n:
print root
return root
else:
newguess()
您致电oldguess()
,因此对newguess()
的每次通话都将完全相同:没有“增量行为”。
你可以做的是从一个简单的猜测开始 - 例如将其作为属性传递,然后继续改进猜测:
def newguess(guess,n):
threshold = 1e-5
root = 0.5 * (guess + n / guess)
if abs(root**2-n) < threshold:
return root
else:
return newguess(root,n) #reuse the previous guess and return
print newguess(oldguess(n),n)
使用@JoranBeasley所描述的容忍机制。
还有一个更好地使用oldguess
的参数:
def oldguess(n):
root = n /2
return root
通常使用全局变量是一个坏主意,对于print
结果, I / O (如input
和print
的方法不应该是相同的由实用方法处理。
所以完整的代码是:
def oldguess(n):
root = n /2
return root
def newguess(guess,n) :
threshold = 1e-5
root = 0.5 * (guess + n / guess)
if abs(root**2 - n) < threshold :
return root
else :
return newguess(root,n) #reuse the previous guess
n = float(input("Which number's square root would you want to compute? " ))
print(newguess(oldguess(n),n))