Я работал с некоторыми функциями, которые выполняют высокоточные вычисления с использованием библиотеки 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