1515#include "scalar_ops.h"
1616#include "dragon4.h"
1717#include "dtype.h"
18+ #include "lock.h"
19+ #include "utilities.h"
1820
1921// For IEEE 754 binary128 (quad precision), we need 36 decimal digits
2022// to guarantee round-trip conversion (string -> parse -> equals original value)
2123// Formula: ceil(1 + MANT_DIG * log10(2)) = ceil(1 + 113 * 0.30103) = 36
2224// src: https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format
2325#define SLEEF_QUAD_DECIMAL_DIG 36
2426
25- #if PY_VERSION_HEX < 0x30d00b3
26- static PyThread_type_lock sleef_lock ;
27- #define LOCK_SLEEF PyThread_acquire_lock(sleef_lock, WAIT_LOCK)
28- #define UNLOCK_SLEEF PyThread_release_lock(sleef_lock)
29- #else
30- static PyMutex sleef_lock = {0 };
31- #define LOCK_SLEEF PyMutex_Lock(&sleef_lock)
32- #define UNLOCK_SLEEF PyMutex_Unlock(&sleef_lock)
33- #endif
34-
35-
36-
3727
3828QuadPrecisionObject *
3929QuadPrecision_raw_new (QuadBackendType backend )
@@ -207,14 +197,23 @@ QuadPrecision_from_object(PyObject *value, QuadBackendType backend)
207197 else if (PyUnicode_Check (value )) {
208198 const char * s = PyUnicode_AsUTF8 (value );
209199 char * endptr = NULL ;
210- if (backend == BACKEND_SLEEF ) {
211- self -> value .sleef_value = Sleef_strtoq (s , & endptr );
200+ int err = cstring_to_quad (s , backend , & self -> value , & endptr , true);
201+ if (err < 0 ) {
202+ PyErr_SetString (PyExc_ValueError , "Unable to parse string to QuadPrecision" );
203+ Py_DECREF (self );
204+ return NULL ;
212205 }
213- else {
214- self -> value .longdouble_value = strtold (s , & endptr );
206+ }
207+ else if (PyBytes_Check (value )) {
208+ const char * s = PyBytes_AsString (value );
209+ if (s == NULL ) {
210+ Py_DECREF (self );
211+ return NULL ;
215212 }
216- if (* endptr != '\0' || endptr == s ) {
217- PyErr_SetString (PyExc_ValueError , "Unable to parse string to QuadPrecision" );
213+ char * endptr = NULL ;
214+ int err = cstring_to_quad (s , backend , & self -> value , & endptr , true);
215+ if (err < 0 ) {
216+ PyErr_SetString (PyExc_ValueError , "Unable to parse bytes to QuadPrecision" );
218217 Py_DECREF (self );
219218 return NULL ;
220219 }
@@ -242,21 +241,21 @@ QuadPrecision_from_object(PyObject *value, QuadBackendType backend)
242241 const char * type_cstr = PyUnicode_AsUTF8 (type_str );
243242 if (type_cstr != NULL ) {
244243 PyErr_Format (PyExc_TypeError ,
245- "QuadPrecision value must be a quad, float, int, string, array or sequence, but got %s "
244+ "QuadPrecision value must be a quad, float, int, string, bytes, array or sequence, but got %s "
246245 "instead" ,
247246 type_cstr );
248247 }
249248 else {
250249 PyErr_SetString (
251250 PyExc_TypeError ,
252- "QuadPrecision value must be a quad, float, int, string, array or sequence, but got an "
251+ "QuadPrecision value must be a quad, float, int, string, bytes, array or sequence, but got an "
253252 "unknown type instead" );
254253 }
255254 Py_DECREF (type_str );
256255 }
257256 else {
258257 PyErr_SetString (PyExc_TypeError ,
259- "QuadPrecision value must be a quad, float, int, string, array or sequence, but got an "
258+ "QuadPrecision value must be a quad, float, int, string, bytes, array or sequence, but got an "
260259 "unknown type instead" );
261260 }
262261 Py_DECREF (self );
@@ -636,13 +635,6 @@ PyTypeObject QuadPrecision_Type = {
636635int
637636init_quadprecision_scalar (void )
638637{
639- #if PY_VERSION_HEX < 0x30d00b3
640- sleef_lock = PyThread_allocate_lock ();
641- if (sleef_lock == NULL ) {
642- PyErr_NoMemory ();
643- return -1 ;
644- }
645- #endif
646638 QuadPrecision_Type .tp_base = & PyFloatingArrType_Type ;
647639 return PyType_Ready (& QuadPrecision_Type );
648640}
0 commit comments