Как решить "OverflowError: int слишком большой, чтобы конвертировать в float"? - PullRequest
1 голос
/ 06 октября 2019

Напишите функцию, которая вычисляет это выражение, добавляя термины, пока абсолютное значение следующего термина не станет меньше указанного допуска tol или пока не будет добавлено не более nmax терминов.

Iпопробовал 'Import Decimal from Decimal' и float (c), но это не сработало.

import math

def sin_taylor(x, tol=1e-7, nmax=100):

    b=0
    for i in range (nmax):
        e = float(2*i+1)
        c=float(math.factorial(e))
        #print(c)
        #print(b)
        a=((((-1)**i))*(x**(e))/c)
        b+=a
    return b

Когда я утверждаю sin_taylor(0)==0, это дает 0, но когда я утверждаю math.isclose(sin_taylor(math.pi/2),0.999999943741051), это дает a=((-1)**i*d)/c OverflowError: int too large to convert to float

Ответы [ 2 ]

0 голосов
/ 06 октября 2019

Во-первых, я не могу понять, почему вы считаете, что sin(math.pi/2) должно быть близко к 0.999999999943741051? На самом деле, оно должно быть ровно 1.

Во-вторых, наиболее существенная проблема в вашем алгоритме состоит в том, что в какой-то момент a становится настолько маленьким, что добавление его к b ничего не меняет. Если вы прервете цикл в этой точке, у вас не будет этих очень больших значений c, например:

def sin_taylor(x, tol=1e-7, nmax=100):
    b=0
    for i in range (nmax):
        e = float(2*i+1)
        c=float(math.factorial(e))
        #print(i, c, b)
        a=((((-1)**i))*(x**(e))/c)
        b0 = b
        b += a
        if b0 == b:
            break
    return b
0 голосов
/ 06 октября 2019

Попробуйте преобразовать числовые значения в десятичные, например:

import math
import decimal


def sin_taylor(x, tol=1e-7, nmax=100):
    decimal.getcontext().prec = 90
    b=0
    for i in range (nmax):
        e = (2*i+1)
        c=(math.factorial(e))
        a = (-1)**i*decimal.Decimal(x)**(e)/c
        b0 = b
        b += a
        if b0 == b:
            print(i)
            break
    return b


print(sin_taylor(math.pi/2))
print(math.isclose(sin_taylor(math.pi/2), 1))
...