Аппроксимация квадратного корня с заданным количеством десятичных знаков - PullRequest
1 голос
/ 02 ноября 2019

Мне нужно сделать программу, которая читает 2 ввода: 1-е содержит неотрицательное целое число n, не более 1 миллиарда (109), 2-е содержит неотрицательное целое число k (желаемая точность, измеренная дробными цифрами),не более 10 тысяч (104). Программа должна распечатать одно число на стандартный вывод. Это число должно быть квадратным корнем из n, взятым с точностью до k дробных цифр, всегда округляя вниз всякий раз, когда необходимо некоторое округление. (В случае, когда k = 0, результат должен быть округлен до ближайшего целого числа).

Это моя вторая задача, и я написал приведенный ниже код для его вычисления с использованием метода Ньютона.

Программа может свободно предполагать, что ввод будет соответствовать вышеуказанным условиям

Программа работает, но число десятичных разрядов не всегда корректно, чтобы решить эту проблему, я попытался добавить некоторое условие для увеличения getcontext (). Предварительно одно единство в соответствии с первым прочитанным числом. Но не решил проблему, так как для: - x <10 ^ 2: результат правильный - x> = 10 ^ 2 & x <10 ^ 4: результат правильный unitl x = 3000, тогда десятичная позиция неверна -1. </p>

from decimal import *
from _decimal import Decimal



def sqrt(x):

    last_guess = x/2.0
    error = (1/(10**y))

    while True:
        guess = Decimal((last_guess + x/last_guess )/2)
        if abs(Decimal(guess) - Decimal(last_guess)) < error:  # example threshold
            return Decimal(guess)
        last_guess = Decimal(guess)
        print(last_guess)


x = int(input("Calculate the square root  of : "))

y = int(input("Decimal positions : "))

if x < 10**2:
    getcontext().prec = y + 1

if x >= 10**2 and x < 10**4:
    getcontext().prec = y + 2

if x >= 10**4 and x < 10**6:
    getcontext().prec = y + 3

if x >= 10**6 and x < 10**8:
    getcontext().prec = y + 4

if x >= 10**8 and x < 10**10:
    getcontext().prec = y + 5

if x >= 10**10 and x < 10**12:
    getcontext().prec = y + 6

if x >= 10**12 and x < 10**14:
    getcontext().prec = y + 7

a =sqrt(x)

if x < 10**2:
    getcontext().prec = y + 1

if x >= 10**2 and x < 10**4:
    getcontext().prec = y + 2

if x >= 10**4 and x < 10**6:
    getcontext().prec = y + 3

if x >= 10**6 and x < 10**8:
    getcontext().prec = y + 4

if x >= 10**8 and x < 10**10:
    getcontext().prec = y + 5

if x >= 10**10 and x < 10**12:
    getcontext().prec = y + 6

if x >= 10**12 and x < 10**14:
    getcontext().prec = y + 7


print("The square root of ",x," is : ", Decimal(a))
# print("The original number: ", Decimal(a)**2)

Для ввода

8765 8

ваша программа должна распечатать

93.62157870

Для ввода

3000 3

ваша программа должна распечатать

54,772

Ответы [ 2 ]

0 голосов
/ 05 ноября 2019

Спасибо за ваш ответ, но я должен использовать метод Ньютона, мой код работает, но он не всегда вводит правильные десятичные знаки, например:

ПРАВИЛЬНО:

x = 10y = 3 результат: 3.162

ПРАВИЛЬНО:

x = 1261 y = 3 результат: 35,510

НЕПРАВИЛЬНО x = 26 y = 3 результат: 5.10 (должно быть 5099)

from decimal import *
from _decimal import Decimal

def sqrt(x):


error = (1/(10**(y+1)))
last_guess = x/2
while True:

    guess = Decimal((last_guess + x / last_guess) / 2)
    if abs(Decimal(guess) - Decimal(last_guess)) < error:
        return Decimal(guess)
    elif guess == last_guess:
        print("guess=last_guess")
        print(" a * a = ", Decimal(guess**2))
        print(guess)

    else:
        last_guess = Decimal(guess)

    # Enter values

    x = int(input("Calculate the square root of: "))

    y = int(input("Decimal positions : "))

    # set decimal places

    c= y


    getcontext().prec = y + 1

    # add one decimal place each time the square root of x increse of 10**2

    if x < 10**2:

        getcontext().prec = c + 1

    if x >= 10**2 and x < 10**4:

        getcontext().prec = c + 2

    if x >= 10**4 and x < 10**6:

        getcontext().prec = c + 3


    if x >= 10**6 and x < 10**8:

        getcontext().prec = c + 4

    if x >= 10**8 and x <= 10**9:

        getcontext().prec = c + 5

        # find the square root

    a =sqrt(x)


    print(Decimal(a))
0 голосов
/ 02 ноября 2019

Попробуй это. Если вы столкнетесь с той же проблемой, прокомментируйте ее, и я постараюсь увидеть, что происходит. У меня также есть вопрос: хотите ли вы, чтобы k было числом десятичных знаков после «.»или просто общее количество мест? Программа, которую я здесь имею, сделает ее точной после '.'всегда точность, которую вы хотите. После программы я покажу вам другой способ сделать это.

from decimal import *
import sys

print("If you want to stop the program, press q")

while True:
    n_int = input("Calculate the square root of: ")

    if str(n_int) == 'q':
        sys.exit()
    else:
        k_dec = int(input("Decimal positions: "))
        n_int = int(n_int)

    temp = Context(prec=k_dec,rounding=ROUND_FLOOR,
                   Emax=999999999,Emin=0)
    setcontext(temp)
    with_k = Decimal(n_int).sqrt()

    after_dec = k_dec - len(str(with_k).split('.')[1])
    context = Context(prec=(k_dec + after_dec),rounding=ROUND_FLOOR,
                      Emax=999999999,Emin=0)

    # prec in Decimal includes __.___ = 5 and __._ = 3 

    setcontext(context)
    sqrt = Decimal(n_int).sqrt()

    if k_dec == 0:
        sqrt = sqrt.to_integral_exact()

    print(f"sqrt: {sqrt}")

Если вы хотите, чтобы ОБЩЕЕ количество десятичных разрядов было просто удалить все после with_k = Decimal (n_int) .sqrt () идобавить печать (f "sqrt {with_k}") после этой строки.

...