Python 使用牛顿法求平方根(错误!)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12850100/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Finding the square root using Newton's method (errors!)
提问by user1739537
I'm working to finish a math problem that approximates the square root of a number using Newton's guess and check method in Python. The user is supposed to enter a number, an initial guess for the number, and how many times they want to check their answer before returning. To make things easier and get to know Python (I've only just started learning the language a couple of months ago) I broke it up into a number of smaller functions; the problem now, though, is that I'm having trouble calling each function and passing the numbers through.
我正在努力完成一个数学问题,该问题使用 Python 中的牛顿猜测和检查方法来逼近一个数字的平方根。用户应该输入一个数字、对该数字的初步猜测,以及在返回之前他们想要检查答案的次数。为了让事情变得更容易并了解 Python(我几个月前才刚刚开始学习这门语言),我将它分解成许多更小的函数;但是,现在的问题是我在调用每个函数和传递数字时遇到了麻烦。
Here is my code, with comments to help (each function is in order of use):
这是我的代码,有帮助的注释(每个函数都按使用顺序排列):
# This program approximates the square root of a number (entered by the user)
# using Newton's method (guess-and-check). I started with one long function,
# but after research, have attempted to apply smaller functions on top of each
# other.
# * NEED TO: call functions properly; implement a counting loop so the
# goodGuess function can only be accessed the certain # of times the user
# specifies. Even if the - .001 range isn't reached, it should return.
# sqrtNewt is basically the main, which initiates user input.
def sqrtNewt():
# c equals a running count initiated at the beginning of the program, to
# use variable count.
print("This will approximate the square root of a number, using a guess-and-check process.")
x = eval(input("Please type in a positive number to find the square root of: "))
guess = eval(input("Please type in a guess for the square root of the number you entered: "))
count = eval(input("Please enter how many times would you like this program to improve your initial guess: "))
avg = average(guess, x)
g, avg = improveG(guess, x)
final = goodGuess(avg, x)
guess = square_root(guess, x, count)
compare(guess, x)
# Average function is called; is the first step that gives an initial average,
# which implements through smaller layers of simple functions stacked on each
# other.
def average(guess, x) :
return ((guess + x) / 2)
# An improvement function which builds upon the original average function.
def improveG(guess, x) :
return average(guess, x/guess)
# A function which determines if the difference between guess X guess minus the
# original number results in an absolute vale less than 0.001. Not taking
# absolute values (like if guess times guess was greater than x) might result
# in errors
from math import *
def goodGuess(avg, x) :
num = abs(avg * avg - x)
return (num < 0.001)
# A function that, if not satisfied, continues to "tap" other functions for
# better guess outputs. i.e. as long as the guess is not good enough, keep
# improving the guess.
def square_root(guess, x, count) :
while(not goodGuess(avg, x)):
c = 0
c = c + 1
if (c < count):
guess = improveG(guess, x)
elif (c == count):
return guess
else :
pass
# Function is used to check the difference between guess and the sqrt method
# applied to the user input.
import math
def compare(guess, x):
diff = math.sqrt(x) - guess
print("The following is the difference between the approximation")
print("and the Math.sqrt method, not rounded:", diff)
sqrtNewt()
Currently, I get this error: g, avg = improveG(guess, x)
TypeError: 'float' object is not iterable.The final function uses the final iteration of the guess to subtract from the math square root method, and returns the overall difference.
Am I even doing this right? Working code would be appreciated, with suggestions, if you can provide it. Again, I'm a newbie, so I apologize for misconceptions or blind obvious errors.
目前,我收到此错误:g, avg = improveG(guess, x)
TypeError: 'float' object is not iterable.最终函数使用猜测的最终迭代从数学平方根方法中减去,并返回整体差异。我这样做对吗?如果您能提供建议,工作代码将不胜感激。再次,我是一个新手,所以我为误解或盲目的明显错误道歉。
采纳答案by root
Implementation of the newton method:
牛顿法的实现:
It should be fairly easy to add little tweaks to it when needed. Try, and tell us when you get stuck.
在需要时添加一些小调整应该是相当容易的。尝试一下,当您遇到困难时告诉我们。
from math import *
def average(a, b):
return (a + b) / 2.0
def improve(guess, x):
return average(guess, x/guess)
def good_enough(guess, x):
d = abs(guess*guess - x)
return (d < 0.001)
def square_root(guess, x):
while(not good_enough(guess, x)):
guess = improve(guess, x)
return guess
def my_sqrt(x):
r = square_root(1, x)
return r
>>> my_sqrt(16)
4.0000006366929393
NOTE: you will find enough exaples on how to use raw input here at SO or googling, BUT, if you are counting loops, the c=0has to be outside the loop, or you will be stuck in an infinite loop.
注意:您会在 SO 或谷歌搜索中找到足够的关于如何使用原始输入的示例,但是,如果您正在计算循环,则c=0必须在循环之外,否则您将陷入无限循环。
Quiqk and dirty, lots of ways to improve:
Quiqk和肮脏,很多改进的方法:
from math import *
def average(a, b):
return (a + b) / 2.0
def improve(guess, x):
return average(guess, x/guess)
def square_root(guess, x, c):
guesscount=0
while guesscount < c :
guesscount+=1
guess = improve(guess, x)
return guess
def my_sqrt(x,c):
r = square_root(1, x, c)
return r
number=int(raw_input('Enter a positive number'))
i_guess=int(raw_input('Enter an initial guess'))
times=int(raw_input('How many times would you like this program to improve your initial guess:'))
answer=my_sqrt(number,times)
print 'sqrt is approximately ' + str(answer)
print 'difference between your guess and sqrt is ' + str(abs(i_guess-answer))
回答by user448810
Here's a rather different function to compute square roots; it assumes nis non-negative:
这是一个相当不同的计算平方根的函数;它假设n是非负的:
def mySqrt(n):
if (n == 0):
return 0
if (n < 1):
return mySqrt(n * 4) / 2
if (4 <= n):
return mySqrt(n / 4) * 2
x = (n + 1.0) / 2.0
x = (x + n/x) / 2.0
x = (x + n/x) / 2.0
x = (x + n/x) / 2.0
x = (x + n/x) / 2.0
x = (x + n/x) / 2.0
return x
This algorithm is similar to Newton's, but not identical. It was invented by a Greek mathematician named Heron (his name is sometimes spelled Hero) living in Alexandria, Egypt in the first century (about two thousand years ago). Heron's recurrence formula is simpler than Newton's; Heron used x' = (x + n/x) / 2where Newton used x' = x - (x^2 - n) / 2x.
该算法与牛顿算法相似,但不完全相同。它是由一位名叫 Heron(他的名字有时拼写为 Hero)的希腊数学家在公元一世纪(大约 2000 年前)居住在埃及的亚历山大港发明的。Heron 的递推公式比 Newton 的更简单;Heron 用x' = (x + n/x) / 2在 Newton 用过的地方x' = x - (x^2 - n) / 2x。
The first test is a special case on zero; without it, the (n < 1)test causes an infinite loop. The next two tests normalize nto the range 1 < n <= 4; making the range smaller means that we can easily compute an initial approximation to the square root of n, which is done in the first computation of x, and then "unroll the loop" and iterate the recurrence equation a fixed number of times, thus eliminating the need for testing and recurring if the difference between two successive loops is too large.
第一个测试是零的特例;没有它,(n < 1)测试会导致无限循环。接下来的两个测试将n归一化为范围1 < n <= 4;使范围更小意味着我们可以轻松地计算n 的平方根的初始近似值,这是在x的第一次计算中完成的,然后“展开循环”并迭代递归方程固定次数,从而消除如果两个连续循环之间的差异太大,则需要测试和重复。
By the way, Heron was a pretty interesting fellow. In addition to inventing a method for calculating square roots, he built a working jet engine, a coin-operated vending machine, and lots of other neat stuff!
顺便说一下,苍鹭是一个非常有趣的人。除了发明了计算平方根的方法之外,他还建造了一个可以工作的喷气发动机、一个投币式自动售货机,以及许多其他巧妙的东西!
You can read more about computing square roots at my blog.
您可以在我的博客上阅读有关计算平方根的更多信息。
回答by Kendrick Ledet
The chosen answer is a bit convoluted...no disrespect to the OP.
选择的答案有点令人费解......没有不尊重OP。
For anyone who ever Googles this in the future, this is my solution:
对于将来使用 Google 搜索此问题的任何人,这是我的解决方案:
def check(x, guess):
return (abs(guess*guess - x) < 0.001)
def newton(x, guess):
while not check(x, guess):
guess = (guess + (x/guess)) / 2.0
return guess
print newton(16, 1)
回答by Shrey
it shouldnt have to be that complicated i wrote this up
它不应该那么复杂,我写了这个
def squareroot(n,x):
final = (0.5*(x+(n/x)))
print (final)
for i in range(0,10):
final = (0.5*(final+(n/final)))
print (final)
or you could change it to be like this
或者你可以把它改成这样
n = float(input('What number would you like to squareroot?'))
x = float(input('Estimate your answer'))
final = (0.5*(x+(n/x)))
print (final)
for i in range(0,10):
final = (0.5*(final+(n/final)))
print (final)
回答by HighOnFloyd
All you need to know is the nth term in the sequence. From the Leibniz series, we know this is ((-1)**n)/((2*n)+1). Just sum this series for all i with an initial condition of zero and you're set.
您只需要知道序列中的第 n 项。从莱布尼茨级数中,我们知道这是 ((-1)**n)/((2*n)+1)。只需在初始条件为零的情况下将所有 i 的这个系列相加就可以了。
def myPi(n):
pi=0
for i in range(0,n):
pi=pi+((-1)**i)/((2*i)+1)
return 4*pi
print (myPi(10000))

