44#include <stdlib.h>
55#include <math.h>
66#include <string.h>
7+ #include <float.h>
78
89#define PY_ARRAY_UNIQUE_SYMBOL QuadPrecType_ARRAY_API
910#define NPY_NO_DEPRECATED_API NPY_2_0_API_VERSION
@@ -684,7 +685,22 @@ QuadPrecision_reduce(QuadPrecisionObject *self, PyObject *Py_UNUSED(ignored))
684685 return NULL ;
685686 }
686687
687- PyObject * args = PyTuple_Pack (2 , data , backend_obj );
688+ PyObject * args ;
689+ if (self -> backend == BACKEND_LONGDOUBLE ) {
690+ // Tag longdouble payloads with the platform's LDBL_MANT_DIG
691+ PyObject * fmt = PyLong_FromLong ((long )LDBL_MANT_DIG );
692+ if (fmt == NULL ) {
693+ Py_DECREF (data );
694+ Py_DECREF (backend_obj );
695+ Py_DECREF (reconstruct );
696+ return NULL ;
697+ }
698+ args = PyTuple_Pack (3 , data , backend_obj , fmt );
699+ Py_DECREF (fmt );
700+ }
701+ else {
702+ args = PyTuple_Pack (2 , data , backend_obj );
703+ }
688704 Py_DECREF (data );
689705 Py_DECREF (backend_obj );
690706 if (args == NULL ) {
@@ -703,7 +719,8 @@ QuadPrecision_from_raw_bytes(PyObject *Py_UNUSED(module), PyObject *args)
703719{
704720 Py_buffer view ;
705721 const char * backend_str = "sleef" ;
706- if (!PyArg_ParseTuple (args , "y*|s" , & view , & backend_str )) {
722+ int ld_format = -1 ; // source LDBL_MANT_DIG for longdouble; -1 = not provided
723+ if (!PyArg_ParseTuple (args , "y*|si" , & view , & backend_str , & ld_format )) {
707724 return NULL ;
708725 }
709726
@@ -727,6 +744,17 @@ QuadPrecision_from_raw_bytes(PyObject *Py_UNUSED(module), PyObject *args)
727744 return NULL ;
728745 }
729746
747+ if (backend == BACKEND_LONGDOUBLE && ld_format != -1 &&
748+ ld_format != LDBL_MANT_DIG ) {
749+ PyErr_Format (PyExc_ValueError ,
750+ "Cannot unpickle a 'longdouble' QuadPrecision created on a "
751+ "platform with a different long double format "
752+ "(LDBL_MANT_DIG=%d) than this one (LDBL_MANT_DIG=%d)." ,
753+ ld_format , (int )LDBL_MANT_DIG );
754+ PyBuffer_Release (& view );
755+ return NULL ;
756+ }
757+
730758 QuadPrecisionObject * self = QuadPrecision_raw_new (backend );
731759 if (self == NULL ) {
732760 PyBuffer_Release (& view );
@@ -746,7 +774,7 @@ static PyMethodDef QuadPrecision_methods[] = {
746774 {"as_integer_ratio" , (PyCFunction )QuadPrecision_as_integer_ratio , METH_NOARGS ,
747775 "Return a pair of integers whose ratio is exactly equal to the original value." },
748776 {"__reduce__" , (PyCFunction )QuadPrecision_reduce , METH_NOARGS ,
749- "Support pickling: return (from_raw_bytes, (raw_bytes, backend))." },
777+ "Support pickling: return (from_raw_bytes, (raw_bytes, backend[, ld_format] ))." },
750778 {NULL , NULL , 0 , NULL } /* Sentinel */
751779};
752780
0 commit comments