Преобразование из mpmath в float128 / longdouble numpy фактически приводит к точности float64 / double - PullRequest
0 голосов
/ 11 марта 2019

Я работал с некоторыми функциями, которые выполняют высокоточные вычисления с использованием библиотеки mpmath Python.Однако теперь мне нужно преобразовать некоторые результаты вычислений mpmath в формате mpf в numpy longdouble (заплатив, конечно, цену потери точности / цифр).

Если для преобразования числа требуется меньше цифр, чем может обработать двойной Python, очевидное преобразование работает:

x = mp.mpmathify("1e-300")
float(x)
np.longdouble(x)

Предоставление вывода:

In [1]: x = mp.mpmathify("1e-300")

In [2]: float(x)
Out[2]: 1e-300

In [3]: np.longdouble(x)
Out[3]: 1.00000000000000002506e-300

Теперь, если для преобразования числа требуется больше цифр, чем может обработать стандартный двойной Python, но меньше, чем для длинного двойника системы, можно ожидать, что float(x) вернет ноль, а np.longdouble(x) сохранит фактическую преобразованную версию изmpf объект.Однако это не то, что происходит:

In [4]: x = mp.mpmathify("1e-3000")

In [5]: x
Out[5]: mpf('1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-3000')

In [6]: float(x)
Out[6]: 0.0

In [7]: np.longdouble(x)
Out[7]: 0.0

То же самое происходит, если вместо np.longdouble(x) используется np.float128(x).Кроме того, то же самое происходит, если я пытаюсь сохранить значение mpf в массиве типа long long:

In [8]: arr = np.empty((1, 1), dtype=np.longdouble)

In [9]: arr[0, 0] = x

In [10]: arr[0, 0]
Out[10]: 0.0

Мои вопросы:

(1), почему это происходит?У меня сложилось впечатление, что когда мы говорим numpy конвертировать в long double или float128, он сначала конвертируется в double или float64, теряя точность - что затем побеждает цель.

(2) как я могу делать то, что хотелвыше, то есть, чтобы преобразовать число, сгенерированное из mpmath, в простой двойной double или float128, не сворачивая его в ноль, когда число должно соответствовать длинному double или float128?

В случае, если выинтересно, вот мой самый низкий положительный длинный двойной системы:

In [11]: np.nextafter(np.longdouble(0),1)
Out[11]: 4e-4951
...