Арифметическая ошибка с плавающей точкой

Я использую следующую функцию, чтобы приблизить производную функции в точке:

def prime_x(f, x, h):

    if not f(x+h) == f(x) and not h == 0.0: 
        return (f(x+h) - f(x)) / h
    else:
        raise PrecisionError

В качестве теста я прохожуf какfx а такжеx как 3.0. гдеfx является:

def fx(x):

    import math
    return math.exp(x)*math.sin(x)

У которого естьexp(x)*(sin(x)+cos(x)) как производная. Теперь, согласно Google и моему калькулятору

exp(3)*(sin(3)+cos(3)) = -17.050059.

Все идет нормально. Но когда я решил проверить функцию с небольшими значениями дляh Я получил следующее:

print prime_x(fx, 3.0, 10**-5)
-17.0502585578
print prime_x(fx, 3.0, 10**-10)
-17.0500591423
 print prime_x(fx, 3.0, 10**-12)
-17.0512493014
print prime_x(fx, 3.0, 10**-13)
-17.0352620898
print prime_x(fx, 3.0, 10**-16)
__main__.PrecisionError: Mantissa is 16 digits

Почему ошибка увеличивается при уменьшении h (после определенной точки)? Я ожидал обратного, покаf(x+h) был равенf(x).

Ответы на вопрос(2)

Ваш ответ на вопрос