summaryrefslogtreecommitdiffstats
path: root/Modules/mathmodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/mathmodule.c')
-rw-r--r--Modules/mathmodule.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c
index 8bd38d0..66e88b6 100644
--- a/Modules/mathmodule.c
+++ b/Modules/mathmodule.c
@@ -1596,6 +1596,47 @@ math_factorial(PyObject *module, PyObject *arg)
/*[clinic input]
+math.fma
+
+ x: double
+ y: double
+ z: double
+ /
+
+Fused multiply-add operation. Compute (x * y) + z with a single round.
+[clinic start generated code]*/
+
+static PyObject *
+math_fma_impl(PyObject *module, double x, double y, double z)
+/*[clinic end generated code: output=4fc8626dbc278d17 input=2ae8bb2a6e0f8b77]*/
+{
+ double r;
+ r = fma(x, y, z);
+
+ /* Fast path: if we got a finite result, we're done. */
+ if (Py_IS_FINITE(r)) {
+ return PyFloat_FromDouble(r);
+ }
+
+ /* Non-finite result. Raise an exception if appropriate, else return r. */
+ if (Py_IS_NAN(r)) {
+ if (!Py_IS_NAN(x) && !Py_IS_NAN(y) && !Py_IS_NAN(z)) {
+ /* NaN result from non-NaN inputs. */
+ PyErr_SetString(PyExc_ValueError, "invalid operation in fma");
+ return NULL;
+ }
+ }
+ else if (Py_IS_FINITE(x) && Py_IS_FINITE(y) && Py_IS_FINITE(z)) {
+ /* Infinite result from finite inputs. */
+ PyErr_SetString(PyExc_OverflowError, "overflow in fma");
+ return NULL;
+ }
+
+ return PyFloat_FromDouble(r);
+}
+
+
+/*[clinic input]
math.trunc
x: object
@@ -2224,6 +2265,7 @@ static PyMethodDef math_methods[] = {
{"fabs", math_fabs, METH_O, math_fabs_doc},
MATH_FACTORIAL_METHODDEF
MATH_FLOOR_METHODDEF
+ MATH_FMA_METHODDEF
MATH_FMOD_METHODDEF
MATH_FREXP_METHODDEF
MATH_FSUM_METHODDEF