8000 Merge pull request #20465 from charris/backport-20360 · numpy/numpy@e1fe715 · GitHub
[go: up one dir, main page]

Skip to content

Commit e1fe715

Browse files
authored
Merge pull request #20465 from charris/backport-20360
BUG: Force ``npymath` ` to respect ``npy_longdouble``
2 parents 1d1f044 + 733574d commit e1fe715

File tree

3 files changed

+50
-21
lines changed

3 files changed

+50
-21
lines changed

numpy/core/include/numpy/npy_common.h

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -356,14 +356,31 @@ typedef unsigned long npy_ulonglong;
356356
typedef unsigned char npy_bool;
357357
#define NPY_FALSE 0
358358
#define NPY_TRUE 1
359-
360-
359+
/*
360+
* `NPY_SIZEOF_LONGDOUBLE` isn't usually equal to sizeof(long double).
361+
* In some certain cases, it may forced to be equal to sizeof(double)
362+
* even against the compiler implementation and the same goes for
363+
* `complex long double`.
364+
*
365+
* Therefore, avoid `long double`, use `npy_longdouble` instead,
366+
* and when it comes to standard math functions make sure of using
367+
* the double version when `NPY_SIZEOF_LONGDOUBLE` == `NPY_SIZEOF_DOUBLE`.
368+
* For example:
369+
* npy_longdouble *ptr, x;
370+
* #if NPY_SIZEOF_LONGDOUBLE == NPY_SIZEOF_DOUBLE
371+
* npy_longdouble r = modf(x, ptr);
372+
* #else
373+
* npy_longdouble r = modfl(x, ptr);
374+
* #endif
375+
*
376+
* See https://github.com/numpy/numpy/issues/20348
377+
*/
361378
#if NPY_SIZEOF_LONGDOUBLE == NPY_SIZEOF_DOUBLE
362-
typedef double npy_longdouble;
363-
#define NPY_LONGDOUBLE_FMT "g"
379< 10000 /code>+
#define NPY_LONGDOUBLE_FMT "g"
380+
typedef double npy_longdouble;
364381
#else
365-
typedef long double npy_longdouble;
366-
#define NPY_LONGDOUBLE_FMT "Lg"
382+
#define NPY_LONGDOUBLE_FMT "Lg"
383+
typedef long double npy_longdouble;
367384
#endif
368385

369386
#ifndef Py_USING_UNICODE

numpy/core/src/multiarray/_multiarray_tests.c.src

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2093,7 +2093,7 @@ PrintFloat_Printf_g(PyObject *obj, int precision)
20932093
}
20942094
else if (PyArray_IsScalar(obj, LongDouble)) {
20952095
npy_longdouble x = PyArrayScalar_VAL(obj, LongDouble);
2096-
PyOS_snprintf(str, sizeof(str), "%.*Lg", precision, x);
2096+
PyOS_snprintf(str, sizeof(str), "%.*" NPY_LONGDOUBLE_FMT, precision, x);
20972097
}
20982098
else{
20992099
double val = PyFloat_AsDouble(obj);

numpy/core/src/npymath/npy_math_internal.h.src

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -480,10 +480,16 @@ NPY_INPLACE @type@ npy_frexp@c@(@type@ x, int* exp)
480480

481481
/**begin repeat
482482
* #type = npy_longdouble, npy_double, npy_float#
483+
* #TYPE = LONGDOUBLE, DOUBLE, FLOAT#
483484
* #c = l,,f#
484485
* #C = L,,F#
485486
*/
486-
487+
#undef NPY__FP_SFX
488+
#if NPY_SIZEOF_@TYPE@ == NPY_SIZEOF_DOUBLE
489+
#define NPY__FP_SFX(X) X
490+
#else
491+
#define NPY__FP_SFX(X) NPY_CAT(X, @c@)
492+
#endif
487493
/*
488494
* On arm64 macOS, there's a bug with sin, cos, and tan where they don't
< EDBE /code>
489495
* raise "invalid" when given INFINITY as input.
@@ -509,7 +515,7 @@ NPY_INPLACE @type@ npy_@kind@@c@(@type@ x)
509515
return (x - x);
510516
}
511517
#endif
512-
return @kind@@c@(x);
518+
return NPY__FP_SFX(@kind@)(x);
513519
}
514520
#endif
515521

@@ -524,7 +530,7 @@ NPY_INPLACE @type@ npy_@kind@@c@(@type@ x)
524530
#ifdef HAVE_@KIND@@C@
525531
NPY_INPLACE @type@ npy_@kind@@c@(@type@ x, @type@ y)
526532
{
527-
return @kind@@c@(x, y);
533+
return NPY__FP_SFX(@kind@)(x, y);
528534
}
529535
#endif
530536
/**end repeat1**/
@@ -555,21 +561,21 @@ npy_@kind@@c@(@type@ x, @type@ y)
555561
#ifdef HAVE_MODF@C@
556562
NPY_INPLACE @type@ npy_modf@c@(@type@ x, @type@ *iptr)
557563
{
558-
return modf@c@(x, iptr);
564+
return NPY__FP_SFX(modf)(x, iptr);
559565
}
560566
#endif
561567

562568
#ifdef HAVE_LDEXP@C@
563569
NPY_INPLACE @type@ npy_ldexp@c@(@type@ x, int exp)
564570
{
565-
return ldexp@c@(x, exp);
571+
return NPY__FP_SFX(ldexp)(x, exp);
566572
}
567573
#endif
568574

569575
#ifdef HAVE_FREXP@C@
570576
NPY_INPLACE @type@ npy_frexp@c@(@type@ x, int* exp)
571577
{
572-
return frexp@c@(x, exp);
578+
return NPY__FP_SFX(frexp)(x, exp);
573579
}
574580
#endif
575581

@@ -592,10 +598,10 @@ NPY_INPLACE @type@ npy_cbrt@c@(@type@ x)
592598
#else
593599
NPY_INPLACE @type@ npy_cbrt@c@(@type@ x)
594600
{
595-
return cbrt@c@(x);
601+
return NPY__FP_SFX(cbrt)(x);
596602
}
597603
#endif
598-
604+
#undef NPY__FP_SFX
599605
/**end repeat**/
600606

601607

@@ -605,10 +611,16 @@ NPY_INPLACE @type@ npy_cbrt@c@(@type@ x)
605611

606612
/**begin repeat
607613
* #type = npy_float, npy_double, npy_longdouble#
614+
* #TYPE = FLOAT, DOUBLE, LONGDOUBLE#
608615
* #c = f, ,l#
609616
* #C = F, ,L#
610617
*/
611-
618+
#undef NPY__FP_SFX
619+
#if NPY_SIZEOF_@TYPE@ == NPY_SIZEOF_DOUBLE
620+
#define NPY__FP_SFX(X) X
621+
#else
622+
#define NPY__FP_SFX(X) NPY_CAT(X, @c@)
623+
#endif
612624
@type@ npy_heaviside@c@(@type@ x, @type@ h0)
613625
{
614626
if (npy_isnan(x)) {
@@ -625,10 +637,10 @@ NPY_INPLACE @type@ npy_cbrt@c@(@type@ x)
625637
}
626638
}
627639

628-
#define LOGE2 NPY_LOGE2@c@
629-
#define LOG2E NPY_LOG2E@c@
630-
#define RAD2DEG (180.0@c@/NPY_PI@c@)
631-
#define DEG2RAD (NPY_PI@c@/180.0@c@)
640+
#define LOGE2 NPY__FP_SFX(NPY_LOGE2)
641+
#define LOG2E NPY__FP_SFX(NPY_LOG2E)
642+
#define RAD2DEG (NPY__FP_SFX(180.0)/NPY__FP_SFX(NPY_PI))
643+
#define DEG2RAD (NPY__FP_SFX(NPY_PI)/NPY__FP_SFX(180.0))
632644

633645
NPY_INPLACE @type@ npy_rad2deg@c@(@type@ x)
634646
{
@@ -783,7 +795,7 @@ npy_divmod@c@(@type@ a, @type@ b, @type@ *modulus)
783795
#undef LOG2E
784796
#undef RAD2DEG
785797
#undef DEG2RAD
786-
798+
#undef NPY__FP_SFX
787799
/**end repeat**/
788800

789801
/**begin repeat

0 commit comments

Comments
 (0)
0