diff options
Diffstat (limited to 'numpy')
| -rw-r--r-- | numpy/core/include/numpy/npy_common.h | 28 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/_multiarray_tests.c.src | 2 | ||||
| -rw-r--r-- | numpy/core/src/npymath/npy_math_internal.h.src | 40 |
3 files changed, 50 insertions, 20 deletions
diff --git a/numpy/core/include/numpy/npy_common.h b/numpy/core/include/numpy/npy_common.h index 57cc592b9..88794ca07 100644 --- a/numpy/core/include/numpy/npy_common.h +++ b/numpy/core/include/numpy/npy_common.h @@ -356,14 +356,32 @@ typedef unsigned long npy_ulonglong; typedef unsigned char npy_bool; #define NPY_FALSE 0 #define NPY_TRUE 1 - - +/* + * `NPY_SIZEOF_LONGDOUBLE` isn't usually equal to sizeof(long double). + * In some certain cases, it may forced to be equal to sizeof(double) + * even against the compiler implementation and the same goes for + * `complex long double`. + * + * Therefore, avoid `long double`, use `npy_longdouble` instead, + * and when it comes to standard math functions make sure of using + * the double version when `NPY_SIZEOF_LONGDOUBLE` == `NPY_SIZEOF_DOUBLE`. + * For example: + * npy_longdouble *ptr, x; + * #if NPY_SIZEOF_LONGDOUBLE == NPY_SIZEOF_DOUBLE + * npy_longdouble r = modf(x, ptr); + * #else + * npy_longdouble r = modfl(x, ptr); + * #endif + * + * See https://github.com/numpy/numpy/issues/20348 + */ #if NPY_SIZEOF_LONGDOUBLE == NPY_SIZEOF_DOUBLE - #define NPY_LONGDOUBLE_FMT "g" + #define NPY_LONGDOUBLE_FMT "g" + typedef double npy_longdouble; #else - #define NPY_LONGDOUBLE_FMT "Lg" + #define NPY_LONGDOUBLE_FMT "Lg" + typedef long double npy_longdouble; #endif -typedef long double npy_longdouble; #ifndef Py_USING_UNICODE #error Must use Python with unicode enabled. diff --git a/numpy/core/src/multiarray/_multiarray_tests.c.src b/numpy/core/src/multiarray/_multiarray_tests.c.src index e945d0771..d7dfa4829 100644 --- a/numpy/core/src/multiarray/_multiarray_tests.c.src +++ b/numpy/core/src/multiarray/_multiarray_tests.c.src @@ -2193,7 +2193,7 @@ PrintFloat_Printf_g(PyObject *obj, int precision) } else if (PyArray_IsScalar(obj, LongDouble)) { npy_longdouble x = PyArrayScalar_VAL(obj, LongDouble); - PyOS_snprintf(str, sizeof(str), "%.*Lg", precision, x); + PyOS_snprintf(str, sizeof(str), "%.*" NPY_LONGDOUBLE_FMT, precision, x); } else{ double val = PyFloat_AsDouble(obj); diff --git a/numpy/core/src/npymath/npy_math_internal.h.src b/numpy/core/src/npymath/npy_math_internal.h.src index dd2424db8..5b418342f 100644 --- a/numpy/core/src/npymath/npy_math_internal.h.src +++ b/numpy/core/src/npymath/npy_math_internal.h.src @@ -477,10 +477,16 @@ NPY_INPLACE @type@ npy_frexp@c@(@type@ x, int* exp) /**begin repeat * #type = npy_longdouble, npy_double, npy_float# + * #TYPE = LONGDOUBLE, DOUBLE, FLOAT# * #c = l,,f# * #C = L,,F# */ - +#undef NPY__FP_SFX +#if NPY_SIZEOF_@TYPE@ == NPY_SIZEOF_DOUBLE + #define NPY__FP_SFX(X) X +#else + #define NPY__FP_SFX(X) NPY_CAT(X, @c@) +#endif /* * On arm64 macOS, there's a bug with sin, cos, and tan where they don't * raise "invalid" when given INFINITY as input. @@ -506,7 +512,7 @@ NPY_INPLACE @type@ npy_@kind@@c@(@type@ x) return (x - x); } #endif - return @kind@@c@(x); + return NPY__FP_SFX(@kind@)(x); } #endif @@ -521,7 +527,7 @@ NPY_INPLACE @type@ npy_@kind@@c@(@type@ x) #ifdef HAVE_@KIND@@C@ NPY_INPLACE @type@ npy_@kind@@c@(@type@ x, @type@ y) { - return @kind@@c@(x, y); + return NPY__FP_SFX(@kind@)(x, y); } #endif /**end repeat1**/ @@ -529,21 +535,21 @@ NPY_INPLACE @type@ npy_@kind@@c@(@type@ x, @type@ y) #ifdef HAVE_MODF@C@ NPY_INPLACE @type@ npy_modf@c@(@type@ x, @type@ *iptr) { - return modf@c@(x, iptr); + return NPY__FP_SFX(modf)(x, iptr); } #endif #ifdef HAVE_LDEXP@C@ NPY_INPLACE @type@ npy_ldexp@c@(@type@ x, int exp) { - return ldexp@c@(x, exp); + return NPY__FP_SFX(ldexp)(x, exp); } #endif #ifdef HAVE_FREXP@C@ NPY_INPLACE @type@ npy_frexp@c@(@type@ x, int* exp) { - return frexp@c@(x, exp); + return NPY__FP_SFX(frexp)(x, exp); } #endif @@ -566,10 +572,10 @@ NPY_INPLACE @type@ npy_cbrt@c@(@type@ x) #else NPY_INPLACE @type@ npy_cbrt@c@(@type@ x) { - return cbrt@c@(x); + return NPY__FP_SFX(cbrt)(x); } #endif - +#undef NPY__FP_SFX /**end repeat**/ @@ -579,10 +585,16 @@ NPY_INPLACE @type@ npy_cbrt@c@(@type@ x) /**begin repeat * #type = npy_float, npy_double, npy_longdouble# + * #TYPE = FLOAT, DOUBLE, LONGDOUBLE# * #c = f, ,l# * #C = F, ,L# */ - +#undef NPY__FP_SFX +#if NPY_SIZEOF_@TYPE@ == NPY_SIZEOF_DOUBLE + #define NPY__FP_SFX(X) X +#else + #define NPY__FP_SFX(X) NPY_CAT(X, @c@) +#endif @type@ npy_heaviside@c@(@type@ x, @type@ h0) { if (npy_isnan(x)) { @@ -599,10 +611,10 @@ NPY_INPLACE @type@ npy_cbrt@c@(@type@ x) } } -#define LOGE2 NPY_LOGE2@c@ -#define LOG2E NPY_LOG2E@c@ -#define RAD2DEG (180.0@c@/NPY_PI@c@) -#define DEG2RAD (NPY_PI@c@/180.0@c@) +#define LOGE2 NPY__FP_SFX(NPY_LOGE2) +#define LOG2E NPY__FP_SFX(NPY_LOG2E) +#define RAD2DEG (NPY__FP_SFX(180.0)/NPY__FP_SFX(NPY_PI)) +#define DEG2RAD (NPY__FP_SFX(NPY_PI)/NPY__FP_SFX(180.0)) NPY_INPLACE @type@ npy_rad2deg@c@(@type@ x) { @@ -756,7 +768,7 @@ npy_divmod@c@(@type@ a, @type@ b, @type@ *modulus) #undef LOG2E #undef RAD2DEG #undef DEG2RAD - +#undef NPY__FP_SFX /**end repeat**/ /**begin repeat |
