как установить точность с плавающей запятой numpy?

Я только что вычислил одно и то же число двумя способами, но в numpy он делает ошибку

[[ 0.910221324013388510820732335560023784637451171875]]
[[-0.9102213240133882887761274105287156999111175537109375]]

это число одинаково до e^(-15), но отличается впоследствии. Как мне лечить эту ошибку?

есть ли способ ограничить точность с плавающей запятой?

поскольку я вычисляю экспоненциальный с помощью этих чисел, Даже небольшие различия приводят к разочаровывающим ошибкам...

3 ответов


вы заботитесь о фактической точности результата или о том, чтобы получить те же самые цифры из ваших двух вычислений?

если вы просто хотите те же цифры, вы можете использовать np.around() округлить результаты до некоторого соответствующего количества знаков после запятой. Однако, делая это, вы только уменьшите точность результата.

если вы действительно хотите вычислить результат более точно, вы можете попробовать использовать np.longdouble введите для ввода массив, который, в зависимости от архитектуры и компилятора, может дать вам 80-или 128-битное представление с плавающей запятой, а не стандартное 64-битное np.double*.

вы можете сравнить примерное количество десятичных знаков точности, используя np.finfo:

print np.finfo(np.double).precision
# 15

print np.finfo(np.longdouble).precision
# 18

обратите внимание, что не все функции numpy будут поддерживать long double - некоторые будут сбрасывать его до double.


* однако некоторые компиляторы (такие как Microsoft Visual C++) всегда будет лечить long double как синоним double в этом случае не было бы никакой разницы в точности между np.longdouble и np.double.


при нормальном использовании numpy числа удваиваются. Это означает, что точность будет меньше 16 цифр. Вот решенная тема, которая содержит ту же проблему ...

Если вам нужно увеличить точность, то вы можете использовать символьные вычисления .... Библиотека!--9-->mpmath ... тихий хороший. Преимущество в том, что вы можете использовать неограниченное точности. Однако вычисления медленнее, чем numpy может сделать.

здесь вот пример:

# The library mpmath is a good solution
>>> import sympy as smp
>>> import mpmath as mp

>>> mp.mp.dps = 50  # Computation precision is 50 digits
# Notice that the difference between x and y is in the digit before last (47th)
>>> x = smp.mpmath.mpf("0.910221324013388510820732335560023784637451171875")
>>> y = smp.mpmath.mpf("0.910221324013388510820732335560023784637451171865")
>>> x - y  # Must be equal to 1e-47 as the difference is on the 47th digit
mpf('1.000014916280995001003481719184726944958705912691304e-47')

вы не можете сделать лучше с numpy. Вы можете рассчитать экспоненты с большей точностью.

smp.exp(x).evalf(20) = 2.4848724344693696167

можно использовать math.ceil.

например, у вас есть:

a = 8.869705968794857
import math
print(math.ceil(a*1e10)/1e10)

возвращает 8.8697059688, i.e значение до 10 знаков после запятой. Изменить 1e10 до 1e15 или любое другое значение, соответственно

в вашем случае это будет:

a =  0.910221324013388510820732335560023784637451171875
a = math.ceil((a*1e15)/1e15)

это даст вам a = 0.910221324013389