[Python-checkins] Move float conversion into a macro. Apply to fsum (GH-11698)

Raymond Hettinger webhook-mailer at python.org
Tue Jan 29 23:40:04 EST 2019


https://github.com/python/cpython/commit/cfd735ea28a2b985598236f955c72c3f0e82e01d
commit: cfd735ea28a2b985598236f955c72c3f0e82e01d
branch: master
author: Raymond Hettinger <rhettinger at users.noreply.github.com>
committer: GitHub <noreply at github.com>
date: 2019年01月29日T20:39:53-08:00
summary:
Move float conversion into a macro. Apply to fsum (GH-11698)
files:
M Modules/mathmodule.c
diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c
index c4353771d960..83dab1269d63 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);


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /