Skip to main content

Modules/mathmodule.c

Source:

cpython 3.14 @ ab2d84fe1023/Modules/mathmodule.c

Modules/mathmodule.c implements the math module. It wraps the C standard library <math.h> functions and adds Python-specific handling for special float values (NaN, infinity, negative zero), the integer-protocol functions (floor, ceil, trunc), and combinatorial functions (comb, perm, gcd, lcm).

Map

LinesSymbolRole
1-200helpers, math_1, math_2Generic one-/two-arg float function wrappers
201-600trig, exp, log wrapperssin, cos, tan, exp, log, log2, log10
601-900math_isclose, math_isfinite, math_isinf, math_isnanFloat predicates
901-1200math_gcd, math_lcmGreatest common divisor with multi-arg support
1201-1500math_comb, math_permBinomial coefficient; permutations
1501-2000math_floor, math_ceil, math_truncInteger protocol dispatch

Reading

Generic float wrappers

math_1 and math_2 handle the boilerplate for one- and two-argument float functions: convert the Python argument to a C double, call the C function, check for errno and NaN/inf error conditions, and return the result.

// Modules/mathmodule.c:1 math_1 (generic wrapper)
static PyObject *
math_1(PyObject *arg, double (*func)(double), int can_overflow)
{
double x = PyFloat_AsDouble(arg);
if (x == -1.0 && PyErr_Occurred()) return NULL;
errno = 0;
double r = func(x);
if (errno == ERANGE) { PyErr_SetString(PyExc_OverflowError, ...); return NULL; }
if (Py_IS_NAN(r) && !Py_IS_NAN(x)) { PyErr_SetString(PyExc_ValueError, ...); return NULL; }
return PyFloat_FromDouble(r);
}

math.floor, math.ceil: integer protocol

math_floor and math_ceil first check for a __floor__/__ceil__ method on the argument type (the integer protocol). Only if absent do they fall through to the C floor()/ceil() functions. This allows custom numeric types to define their own rounding behavior.

// Modules/mathmodule.c:1501 math_floor
static PyObject *
math_floor(PyObject *module, PyObject *number)
{
PyObject *method = _PyObject_LookupSpecial(number, &_Py_ID(__floor__));
if (method != NULL)
return PyObject_CallNoArgs(method);
double x = PyFloat_AsDouble(number);
return PyLong_FromDouble(floor(x));
}

math.isclose

math_isclose(a, b, rel_tol, abs_tol) implements PEP 485. Two floats are considered close if |a-b| <= max(rel_tol * max(|a|, |b|), abs_tol). Special cases: if either value is NaN, return False; if both are infinite with the same sign, return True.

gopy notes

Not yet ported. The planned package path is module/math/. Go's math package covers all the transcendental functions with the same IEEE 754 semantics. The integer-protocol dispatch (__floor__, __ceil__) would need to be implemented as a type-switch in Go.