Skip to content

Commit cfd735e

Browse files
authored
Move float conversion into a macro. Apply to fsum (GH-11698)
1 parent bafa848 commit cfd735e

File tree

1 file changed

+32
-49
lines changed

1 file changed

+32
-49
lines changed

Modules/mathmodule.c

Lines changed: 32 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,29 @@ static const double logpi = 1.144729885849400174143427351353058711647;
7676
static const double sqrtpi = 1.772453850905516027298167483341145182798;
7777
#endif /* !defined(HAVE_ERF) || !defined(HAVE_ERFC) */
7878

79+
80+
/* Version of PyFloat_AsDouble() with in-line fast paths
81+
for exact floats and integers. Gives a substantial
82+
speed improvement for extracting float arguments.
83+
*/
84+
85+
#define ASSIGN_DOUBLE(target_var, obj, error_label) \
86+
if (PyFloat_CheckExact(obj)) { \
87+
target_var = PyFloat_AS_DOUBLE(obj); \
88+
} \
89+
else if (PyLong_CheckExact(obj)) { \
90+
target_var = PyLong_AsDouble(obj); \
91+
if (target_var == -1.0 && PyErr_Occurred()) { \
92+
goto error_label; \
93+
} \
94+
} \
95+
else { \
96+
target_var = PyFloat_AsDouble(obj); \
97+
if (target_var == -1.0 && PyErr_Occurred()) { \
98+
goto error_label; \
99+
} \
100+
}
101+
79102
static double
80103
sinpi(double x)
81104
{
@@ -1323,10 +1346,8 @@ math_fsum(PyObject *module, PyObject *seq)
13231346
goto _fsum_error;
13241347
break;
13251348
}
1326-
x = PyFloat_AsDouble(item);
1349+
ASSIGN_DOUBLE(x, item, error_with_item);
13271350
Py_DECREF(item);
1328-
if (PyErr_Occurred())
1329-
goto _fsum_error;
13301351

13311352
xsave = x;
13321353
for (i = j = 0; j < n; j++) { /* for y in partials */
@@ -1407,12 +1428,16 @@ math_fsum(PyObject *module, PyObject *seq)
14071428
}
14081429
sum = PyFloat_FromDouble(hi);
14091430

1410-
_fsum_error:
1431+
_fsum_error:
14111432
PyFPE_END_PROTECT(hi)
14121433
Py_DECREF(iter);
14131434
if (p != ps)
14141435
PyMem_Free(p);
14151436
return sum;
1437+
1438+
error_with_item:
1439+
Py_DECREF(item);
1440+
goto _fsum_error;
14161441
}
14171442

14181443
#undef NUM_PARTIALS
@@ -2142,37 +2167,9 @@ math_dist_impl(PyObject *module, PyObject *p, PyObject *q)
21422167
}
21432168
for (i=0 ; i<n ; i++) {
21442169
item = PyTuple_GET_ITEM(p, i);
2145-
if (PyFloat_CheckExact(item)) {
2146-
px = PyFloat_AS_DOUBLE(item);
2147-
}
2148-
else if (PyLong_CheckExact(item)) {
2149-
px = PyLong_AsDouble(item);
2150-
if (px == -1.0 && PyErr_Occurred()) {
2151-
goto error_exit;
2152-
}
2153-
}
2154-
else {
2155-
px = PyFloat_AsDouble(item);
2156-
if (px == -1.0 && PyErr_Occurred()) {
2157-
goto error_exit;
2158-
}
2159-
}
2170+
ASSIGN_DOUBLE(px, item, error_exit);
21602171
item = PyTuple_GET_ITEM(q, i);
2161-
if (PyFloat_CheckExact(item)) {
2162-
qx = PyFloat_AS_DOUBLE(item);
2163-
}
2164-
else if (PyLong_CheckExact(item)) {
2165-
qx = PyLong_AsDouble(item);
2166-
if (qx == -1.0 && PyErr_Occurred()) {
2167-
goto error_exit;
2168-
}
2169-
}
2170-
else {
2171-
qx = PyFloat_AsDouble(item);
2172-
if (qx == -1.0 && PyErr_Occurred()) {
2173-
goto error_exit;
2174-
}
2175-
}
2172+
ASSIGN_DOUBLE(qx, item, error_exit);
21762173
x = fabs(px - qx);
21772174
diffs[i] = x;
21782175
found_nan |= Py_IS_NAN(x);
@@ -2213,21 +2210,7 @@ math_hypot(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
22132210
}
22142211
for (i = 0; i < nargs; i++) {
22152212
item = args[i];
2216-
if (PyFloat_CheckExact(item)) {
2217-
x = PyFloat_AS_DOUBLE(item);
2218-
}
2219-
else if (PyLong_CheckExact(item)) {
2220-
x = PyLong_AsDouble(item);
2221-
if (x == -1.0 && PyErr_Occurred()) {
2222-
goto error_exit;
2223-
}
2224-
}
2225-
else {
2226-
x = PyFloat_AsDouble(item);
2227-
if (x == -1.0 && PyErr_Occurred()) {
2228-
goto error_exit;
2229-
}
2230-
}
2213+
ASSIGN_DOUBLE(x, item, error_exit);
22312214
x = fabs(x);
22322215
coordinates[i] = x;
22332216
found_nan |= Py_IS_NAN(x);

0 commit comments

Comments
 (0)