2013-06-20 9 views
2

«Инкапсулируйте этот цикл в функцию square_root, которая принимает как параметр, выбирает разумное значение x и возвращает оценку квадратного корня из.».Упражнение 7.2: Think Python

def square_root(a): 
    x = 2 
    y = (x + a/x)/2 
    epsilon = 0.00000000001 
    if abs(y - x) < epsilon: 
     print y 
    while abs(y - x) > epsilon: 
     x = x + 1 
     y = (x + a/x)/2 
     break 
    else: 
     return 
    print y  
square_root(33) 

до ввода 33 для «a», он оценивает правильный квадратный корень. после этого он начинает прыгать экспоненциально, до такой степени, что когда я отправляю 100 в «a», он полагает, что квадратный корень равен приблизительно 18. Я не знаю, может быть, это характер оценки. Я знаю, как найти точный квадратный корень, но это упражнение из книги «Think Python», и это нужно практиковать с рекурсией и мышлением алгоритмически.

+0

Почему у вас есть 'break' непосредственно в теле вашего' while' цикла? – Blender

+0

это ничего мне не даст, просто пусто. Он будет работать, но не будет печатать 'y' – troychroi

ответ

3

Нельзя увеличивать x на единицу измерения. Вы должны быть настройки x в y (смотреть на Wikipedia article и обратите внимание, как зависит от x2 и так далее):

while abs(y - x) > epsilon: 
    x = y 
    y = (x + a/x)/2 

Вы хотите избавиться от этого break, а также, как это делает ваш while цикл бессмысленно , Ваш окончательный код будет следующим:

def square_root(a): 
    x = 2 
    y = (x + a/x)/2 
    epsilon = 0.00000000001 
    if abs(y - x) < epsilon: 
     print y 
    while abs(y - x) > epsilon: 
     x = y 
     y = (x + a/x)/2 
    print y 

Но все еще есть возможности для улучшения. Вот как я бы писать:

def square_root(a, epsilon=0.001): 
    # Initial guess also coerces `a` to a float 
    x = a/2.0 

    while True: 
     y = (x + a/x)/2 

     if abs(y - x) < epsilon: 
      return y 

     x = y 

Кроме того, поскольку тип с плавающей запятой в Python не имеют бесконечную точность, вы можете получить только около 15 цифр точности в любом случае, так что вы можете также просто удалить epsilon:

def square_root(a): 
    x = a/2.0 

    while True: 
     y = (x + a/x)/2 

     # You've reached Python's max float precision 
     if x == y: 
      return x 

     x = y 

Но эта последняя версия может не завершиться, если y колеблется между двумя значениями.

+0

спасибо. это очень полезно. – troychroi

1

Вот еще один способ; он просто обновляет x вместо y.

def square_root(a): 
    x = a/2.0 
    epsilon = 0.00000001 
    while abs(a - (x**2)) > epsilon: 
     x = (x + a/x)/2 
    return x 
0

так просто, взять х = а, а затем следует Неутон формулы, например:

def square_root(a): 
x = a 
while True: 
    print x 
    y = (x+a/x)/2 
    if abs(y-x) < 0.0000001: 
     break 
    x = y