¿Cómo uso el dtype numpy longdouble?

Estoy tratando de trabajar con el tipo de np.longdouble np.longdouble en mi código Python, y estoy tratando de usar NumPy para manipular los dobles largos que obtengo de un módulo C comstackdo con Cython.

Supongamos que hago esto:

 import numpy as np print np.finfo(np.longdouble) Machine parameters for float128 --------------------------------------------------------------------- precision= 18 resolution= 1e-18 machep= -63 eps= 1.08420217249e-19 negep = -64 epsneg= 5.42101086243e-20 minexp=-16382 tiny= 3.36210314311e-4932 maxexp= 16384 max= 1.18973149536e+4932 nexp = 15 min= -max --------------------------------------------------------------------- a = np.longdouble(1e+346) a Out[4]: inf b = np.longdouble(1e+347) b Out[6]: inf c = a/b /usr/lib/python2.7/site-packages/spyderlib/widgets/externalshell/start_ipython_kernel.py:1: RuntimeWarning: invalid value encountered in longdouble_scalars # -*- coding: utf-8 -*- c Out[8]: nan a.dtype, b.dtype, c.dtype Out[9]: (dtype('float128'), dtype('float128'), dtype('float128')) 

En esencia, está vinculado al mismo problema que en esta pregunta y entiendo que Python primero convierte el 1e+346 en un flotador, cuya representación sería inf . Sin embargo, ¿alguien puede sugerir una solución? ¿Hay alguna forma de crear NumPy longdoubles que no se conviertan primero en flotantes?

Tengo un módulo C que puede generar dobles largos, que quiero usar en una matriz numpy de dtype np.longdouble .

Incluso si la solución implica volver a comstackr Python / NumPy, estoy dispuesto a intentarlo.

Hay algunas cosas que deberías tener en cuenta.

Primero, esto es un desastre. NumPy sabe longdouble y float128 . Desafortunadamente, los nombres son engañosos, la implementación subyacente es doble C largo, que generalmente es (pero no necesariamente siempre) un flotador de 80 bits. (En realidad, puede verlo aquí mirando a “precisión”; 18 dígitos son aproximadamente 60 bits, y el flotador de 80 bits tiene 64 bits en su mantisa. La precisión sería de alrededor de 34 dígitos si se usaran flotadores reales de 128 bits. )

Puede que no haya ninguna forma directa de pasar los dobles largos como argumentos a una función de C, pero si pasa punteros, puede evitar el problema. Por ejemplo, puede pasar los datos de su matriz como uint8 (utilizando myarray.view(dtype='uint8') ) y convertir el puntero al búfer en double double * en su progtwig C. Al menos entonces Python no tiene nada que ver con las conversiones de tipo. (Lo más probable es que no necesite tomar la view porque, después de todo, solo está exportando un puntero al búfer de matriz).

Solo ten en cuenta que este truco se basa en que el comstackdor tenga el mismo tipo de configuración de tipo al comstackr Python y tu progtwig C. Además de las diferencias de precisión, puede haber diferencias de orden de bytes (raramente si los progtwigs se ejecutan en la misma máquina) y diferencias de alineación. My Python parece alinear los elementos longdouble en los bordes de 16 bytes (es decir, siempre hay 6 bytes de ceros por cada elemento), pero el comstackdor de C puede usar una alineación de 10/12/16 bytes.

Por lo que yo sé, los detalles son específicos de la implementación. Por lo tanto, esto es factible pero requiere un cuidado adicional y puede haber problemas de portabilidad.