Почему эта функция возвращает значения, отличные от тех, которые она выводит?

#python

#python

Вопрос:

Вопрос для начинающих — я пытаюсь решить проблему CodeAbbey # 174, «Вычисление числа Пи», и на данный момент я написал функцию, которая точно вычисляет длины сторон правильного многоугольника с 6 * N углами, таким образом приближая окружность.

В приведенном ниже коде функция x (R,d) выводит правильные значения для «h» и «side» (сравните значения, приведенные в примере на CodeAbbey), но когда я прогнал свой код через pythontutor, я увидел, что он возвращает немного другие значения, например 866025403784438700 вместо866025403784438646 для первого значения h .

Может кто-нибудь помочь мне понять, почему это так?

Как вы, вероятно, можете сказать, я любитель. Я взял функцию isqrt отсюда, поскольку метод math.sqrt (x), похоже, дает очень неточные результаты для больших значений x

 
def isqrt(x):
    # Returns the integer square root. This seems to be unproblematic
    if x < 0:
        raise ValueError('square root not defined for negative numbers')
    n = int(x)
    if n == 0:
        return 0
    a, b = divmod(n.bit_length(), 2)
    x = 2**(a b)
    while True:
        y = (x   n//x)//2
        if y >= x:
            return x
        x = y


def x(R,d):
        # given Radius and sidelength of initial polygon,
        # this should return sidelength of new polygon.
    h = isqrt(R**2 - d**2)
    side = isqrt(d**2   (R-h)**2)
    print (h, side)             # the values in this line are slightly
    return (h, side)            # different than the ones here. Why?


def approximate_pi(K,N):
    R = int(10**K)
    d = R // 2
    for i in range(N):
        d = (x(R,d)[1] // 2)
    return int(6 * 2**(N) * d)


print (approximate_pi(18,4))
 

Комментарии:

1. Это больше похоже на артефакт pythontutor, чем на что-то действительно неправильное в вашем коде. pythontutor не является полностью совместимой реализацией Python.

2. Похоже, что pythontutor использует плавающую точку для больших целых чисел, а не целых чисел с многозначностью. Таким образом, большие числа теряют точность.

Ответ №1:

Это артефакт Python Tutor. Это не то, что на самом деле происходит в вашем коде.

При очень кратком взгляде на исходный код Python Tutor кажется, что серверная часть выполнения Python представляет собой слегка взломанный, в основном стандартный экземпляр CPython с отладочным инструментарием bdb , но визуализация выполняется на Javascript. Печатный вывод поступает из стандартного вывода Python, но визуализация выполняется через Javascript, и целые числа Python преобразуются в числовые значения Javascript, теряя точность, поскольку число имеет 64-разрядную плавающую точку.

Ответ №2:

Это связано с округлением до ближайшего целого числа. В вашей функции divmod(n.bit_length(), 2) попробуйте изменить 2 на 2.0, это даст значение, аналогичное тому, которое вы видели на их платеформе.