summaryrefslogtreecommitdiffstats
path: root/Modules/mathmodule.c
diff options
context:
space:
mode:
authorRaymond Hettinger <rhettinger@users.noreply.github.com>2019-01-30 04:39:53 (GMT)
committerGitHub <noreply@github.com>2019-01-30 04:39:53 (GMT)
commitcfd735ea28a2b985598236f955c72c3f0e82e01d (patch)
tree8d1c44034a3a1d70c06a97e56d8abd882cbdf890 /Modules/mathmodule.c
parentbafa8487f77fa076de3a06755399daf81cb75598 (diff)
downloadcpython-cfd735ea28a2b985598236f955c72c3f0e82e01d.zip
cpython-cfd735ea28a2b985598236f955c72c3f0e82e01d.tar.gz
cpython-cfd735ea28a2b985598236f955c72c3f0e82e01d.tar.bz2
Move float conversion into a macro. Apply to fsum (GH-11698)
Diffstat (limited to 'Modules/mathmodule.c')
-rw-r--r--Modules/mathmodule.c81
1 files changed, 32 insertions, 49 deletions
diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c
index c435377..83dab12 100644
--- a/Modules/mathmodule.c
+++ b/Modules/mathmodule.c
@@ -76,6 +76,29 @@ static const double logpi = 1.144729885849400174143427351353058711647;
static const double sqrtpi = 1.772453850905516027298167483341145182798;
#endif /* !defined(HAVE_ERF) || !defined(HAVE_ERFC) */
+
+/* Version of PyFloat_AsDouble() with in-line fast paths
+ for exact floats and integers. Gives a substantial
+ speed improvement for extracting float arguments.
+*/
+
+#define ASSIGN_DOUBLE(target_var, obj, error_label) \
+ if (PyFloat_CheckExact(obj)) { \
+ target_var = PyFloat_AS_DOUBLE(obj); \
+ } \
+ else if (PyLong_CheckExact(obj)) { \
+ target_var = PyLong_AsDouble(obj); \
+ if (target_var == -1.0 && PyErr_Occurred()) { \
+ goto error_label; \
+ } \
+ } \
+ else { \
+ target_var = PyFloat_AsDouble(obj); \
+ if (target_var == -1.0 && PyErr_Occurred()) { \
+ goto error_label; \
+ } \
+ }
+
static double
sinpi(double x)
{
@@ -1323,10 +1346,8 @@ math_fsum(PyObject *module, PyObject *seq)
goto _fsum_error;
break;
}
- x = PyFloat_AsDouble(item);
+ ASSIGN_DOUBLE(x, item, error_with_item);
Py_DECREF(item);
- if (PyErr_Occurred())
- goto _fsum_error;
xsave = x;
for (i = j = 0; j < n; j++) { /* for y in partials */
@@ -1407,12 +1428,16 @@ math_fsum(PyObject *module, PyObject *seq)
}
sum = PyFloat_FromDouble(hi);
-_fsum_error:
+ _fsum_error:
PyFPE_END_PROTECT(hi)
Py_DECREF(iter);
if (p != ps)
PyMem_Free(p);
return sum;
+
+ error_with_item:
+ Py_DECREF(item);
+ goto _fsum_error;
}
#undef NUM_PARTIALS
@@ -2142,37 +2167,9 @@ math_dist_impl(PyObject *module, PyObject *p, PyObject *q)
}
for (i=0 ; i<n ; i++) {
item = PyTuple_GET_ITEM(p, i);
- if (PyFloat_CheckExact(item)) {
- px = PyFloat_AS_DOUBLE(item);
- }
- else if (PyLong_CheckExact(item)) {
- px = PyLong_AsDouble(item);
- if (px == -1.0 && PyErr_Occurred()) {
- goto error_exit;
- }
- }
- else {
- px = PyFloat_AsDouble(item);
- if (px == -1.0 && PyErr_Occurred()) {
- goto error_exit;
- }
- }
+ ASSIGN_DOUBLE(px, item, error_exit);
item = PyTuple_GET_ITEM(q, i);
- if (PyFloat_CheckExact(item)) {
- qx = PyFloat_AS_DOUBLE(item);
- }
- else if (PyLong_CheckExact(item)) {
- qx = PyLong_AsDouble(item);
- if (qx == -1.0 && PyErr_Occurred()) {
- goto error_exit;
- }
- }
- else {
- qx = PyFloat_AsDouble(item);
- if (qx == -1.0 && PyErr_Occurred()) {
- goto error_exit;
- }
- }
+ ASSIGN_DOUBLE(qx, item, error_exit);
x = fabs(px - qx);
diffs[i] = x;
found_nan |= Py_IS_NAN(x);
@@ -2213,21 +2210,7 @@ math_hypot(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
}
for (i = 0; i < nargs; i++) {
item = args[i];
- if (PyFloat_CheckExact(item)) {
- x = PyFloat_AS_DOUBLE(item);
- }
- else if (PyLong_CheckExact(item)) {
- x = PyLong_AsDouble(item);
- if (x == -1.0 && PyErr_Occurred()) {
- goto error_exit;
- }
- }
- else {
- x = PyFloat_AsDouble(item);
- if (x == -1.0 && PyErr_Occurred()) {
- goto error_exit;
- }
- }
+ ASSIGN_DOUBLE(x, item, error_exit);
x = fabs(x);
coordinates[i] = x;
found_nan |= Py_IS_NAN(x);