mirror of https://github.com/python/cpython
Issue #20186: Converted the math module to Argument Clinic.
Patch by Tal Einat.
This commit is contained in:
parent
b813a0e948
commit
c9ea933586
|
@ -0,0 +1,539 @@
|
|||
/*[clinic input]
|
||||
preserve
|
||||
[clinic start generated code]*/
|
||||
|
||||
PyDoc_STRVAR(math_gcd__doc__,
|
||||
"gcd($module, x, y, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"greatest common divisor of x and y");
|
||||
|
||||
#define MATH_GCD_METHODDEF \
|
||||
{"gcd", (PyCFunction)math_gcd, METH_FASTCALL, math_gcd__doc__},
|
||||
|
||||
static PyObject *
|
||||
math_gcd_impl(PyObject *module, PyObject *a, PyObject *b);
|
||||
|
||||
static PyObject *
|
||||
math_gcd(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
PyObject *a;
|
||||
PyObject *b;
|
||||
|
||||
if (!_PyArg_UnpackStack(args, nargs, "gcd",
|
||||
2, 2,
|
||||
&a, &b)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!_PyArg_NoStackKeywords("gcd", kwnames)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = math_gcd_impl(module, a, b);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_ceil__doc__,
|
||||
"ceil($module, x, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return the ceiling of x as an Integral.\n"
|
||||
"\n"
|
||||
"This is the smallest integer >= x.");
|
||||
|
||||
#define MATH_CEIL_METHODDEF \
|
||||
{"ceil", (PyCFunction)math_ceil, METH_O, math_ceil__doc__},
|
||||
|
||||
PyDoc_STRVAR(math_floor__doc__,
|
||||
"floor($module, x, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return the floor of x as an Integral.\n"
|
||||
"\n"
|
||||
"This is the largest integer <= x.");
|
||||
|
||||
#define MATH_FLOOR_METHODDEF \
|
||||
{"floor", (PyCFunction)math_floor, METH_O, math_floor__doc__},
|
||||
|
||||
PyDoc_STRVAR(math_fsum__doc__,
|
||||
"fsum($module, seq, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return an accurate floating point sum of values in the iterable seq.\n"
|
||||
"\n"
|
||||
"Assumes IEEE-754 floating point arithmetic.");
|
||||
|
||||
#define MATH_FSUM_METHODDEF \
|
||||
{"fsum", (PyCFunction)math_fsum, METH_O, math_fsum__doc__},
|
||||
|
||||
PyDoc_STRVAR(math_factorial__doc__,
|
||||
"factorial($module, x, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Find x!.\n"
|
||||
"\n"
|
||||
"Raise a ValueError if x is negative or non-integral.");
|
||||
|
||||
#define MATH_FACTORIAL_METHODDEF \
|
||||
{"factorial", (PyCFunction)math_factorial, METH_O, math_factorial__doc__},
|
||||
|
||||
PyDoc_STRVAR(math_trunc__doc__,
|
||||
"trunc($module, x, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Truncates the Real x to the nearest Integral toward 0.\n"
|
||||
"\n"
|
||||
"Uses the __trunc__ magic method.");
|
||||
|
||||
#define MATH_TRUNC_METHODDEF \
|
||||
{"trunc", (PyCFunction)math_trunc, METH_O, math_trunc__doc__},
|
||||
|
||||
PyDoc_STRVAR(math_frexp__doc__,
|
||||
"frexp($module, x, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return the mantissa and exponent of x, as pair (m, e).\n"
|
||||
"\n"
|
||||
"m is a float and e is an int, such that x = m * 2.**e.\n"
|
||||
"If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0.");
|
||||
|
||||
#define MATH_FREXP_METHODDEF \
|
||||
{"frexp", (PyCFunction)math_frexp, METH_O, math_frexp__doc__},
|
||||
|
||||
static PyObject *
|
||||
math_frexp_impl(PyObject *module, double x);
|
||||
|
||||
static PyObject *
|
||||
math_frexp(PyObject *module, PyObject *arg)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
double x;
|
||||
|
||||
if (!PyArg_Parse(arg, "d:frexp", &x)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = math_frexp_impl(module, x);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_ldexp__doc__,
|
||||
"ldexp($module, x, i, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return x * (2**i).\n"
|
||||
"\n"
|
||||
"This is essentially the inverse of frexp().");
|
||||
|
||||
#define MATH_LDEXP_METHODDEF \
|
||||
{"ldexp", (PyCFunction)math_ldexp, METH_FASTCALL, math_ldexp__doc__},
|
||||
|
||||
static PyObject *
|
||||
math_ldexp_impl(PyObject *module, double x, PyObject *i);
|
||||
|
||||
static PyObject *
|
||||
math_ldexp(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
double x;
|
||||
PyObject *i;
|
||||
|
||||
if (!_PyArg_ParseStack(args, nargs, "dO:ldexp",
|
||||
&x, &i)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!_PyArg_NoStackKeywords("ldexp", kwnames)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = math_ldexp_impl(module, x, i);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_modf__doc__,
|
||||
"modf($module, x, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return the fractional and integer parts of x.\n"
|
||||
"\n"
|
||||
"Both results carry the sign of x and are floats.");
|
||||
|
||||
#define MATH_MODF_METHODDEF \
|
||||
{"modf", (PyCFunction)math_modf, METH_O, math_modf__doc__},
|
||||
|
||||
static PyObject *
|
||||
math_modf_impl(PyObject *module, double x);
|
||||
|
||||
static PyObject *
|
||||
math_modf(PyObject *module, PyObject *arg)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
double x;
|
||||
|
||||
if (!PyArg_Parse(arg, "d:modf", &x)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = math_modf_impl(module, x);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_log__doc__,
|
||||
"log(x, [base=math.e])\n"
|
||||
"Return the logarithm of x to the given base.\n"
|
||||
"\n"
|
||||
"If the base not specified, returns the natural logarithm (base e) of x.");
|
||||
|
||||
#define MATH_LOG_METHODDEF \
|
||||
{"log", (PyCFunction)math_log, METH_VARARGS, math_log__doc__},
|
||||
|
||||
static PyObject *
|
||||
math_log_impl(PyObject *module, PyObject *x, int group_right_1,
|
||||
PyObject *base);
|
||||
|
||||
static PyObject *
|
||||
math_log(PyObject *module, PyObject *args)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
PyObject *x;
|
||||
int group_right_1 = 0;
|
||||
PyObject *base = NULL;
|
||||
|
||||
switch (PyTuple_GET_SIZE(args)) {
|
||||
case 1:
|
||||
if (!PyArg_ParseTuple(args, "O:log", &x)) {
|
||||
goto exit;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (!PyArg_ParseTuple(args, "OO:log", &x, &base)) {
|
||||
goto exit;
|
||||
}
|
||||
group_right_1 = 1;
|
||||
break;
|
||||
default:
|
||||
PyErr_SetString(PyExc_TypeError, "math.log requires 1 to 2 arguments");
|
||||
goto exit;
|
||||
}
|
||||
return_value = math_log_impl(module, x, group_right_1, base);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_log2__doc__,
|
||||
"log2($module, x, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return the base 2 logarithm of x.");
|
||||
|
||||
#define MATH_LOG2_METHODDEF \
|
||||
{"log2", (PyCFunction)math_log2, METH_O, math_log2__doc__},
|
||||
|
||||
PyDoc_STRVAR(math_log10__doc__,
|
||||
"log10($module, x, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return the base 10 logarithm of x.");
|
||||
|
||||
#define MATH_LOG10_METHODDEF \
|
||||
{"log10", (PyCFunction)math_log10, METH_O, math_log10__doc__},
|
||||
|
||||
PyDoc_STRVAR(math_fmod__doc__,
|
||||
"fmod($module, x, y, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return fmod(x, y), according to platform C.\n"
|
||||
"\n"
|
||||
"x % y may differ.");
|
||||
|
||||
#define MATH_FMOD_METHODDEF \
|
||||
{"fmod", (PyCFunction)math_fmod, METH_FASTCALL, math_fmod__doc__},
|
||||
|
||||
static PyObject *
|
||||
math_fmod_impl(PyObject *module, double x, double y);
|
||||
|
||||
static PyObject *
|
||||
math_fmod(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
double x;
|
||||
double y;
|
||||
|
||||
if (!_PyArg_ParseStack(args, nargs, "dd:fmod",
|
||||
&x, &y)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!_PyArg_NoStackKeywords("fmod", kwnames)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = math_fmod_impl(module, x, y);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_hypot__doc__,
|
||||
"hypot($module, x, y, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return the Euclidean distance, sqrt(x*x + y*y).");
|
||||
|
||||
#define MATH_HYPOT_METHODDEF \
|
||||
{"hypot", (PyCFunction)math_hypot, METH_FASTCALL, math_hypot__doc__},
|
||||
|
||||
static PyObject *
|
||||
math_hypot_impl(PyObject *module, double x, double y);
|
||||
|
||||
static PyObject *
|
||||
math_hypot(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
double x;
|
||||
double y;
|
||||
|
||||
if (!_PyArg_ParseStack(args, nargs, "dd:hypot",
|
||||
&x, &y)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!_PyArg_NoStackKeywords("hypot", kwnames)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = math_hypot_impl(module, x, y);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_pow__doc__,
|
||||
"pow($module, x, y, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return x**y (x to the power of y).");
|
||||
|
||||
#define MATH_POW_METHODDEF \
|
||||
{"pow", (PyCFunction)math_pow, METH_FASTCALL, math_pow__doc__},
|
||||
|
||||
static PyObject *
|
||||
math_pow_impl(PyObject *module, double x, double y);
|
||||
|
||||
static PyObject *
|
||||
math_pow(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
double x;
|
||||
double y;
|
||||
|
||||
if (!_PyArg_ParseStack(args, nargs, "dd:pow",
|
||||
&x, &y)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!_PyArg_NoStackKeywords("pow", kwnames)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = math_pow_impl(module, x, y);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_degrees__doc__,
|
||||
"degrees($module, x, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Convert angle x from radians to degrees.");
|
||||
|
||||
#define MATH_DEGREES_METHODDEF \
|
||||
{"degrees", (PyCFunction)math_degrees, METH_O, math_degrees__doc__},
|
||||
|
||||
static PyObject *
|
||||
math_degrees_impl(PyObject *module, double x);
|
||||
|
||||
static PyObject *
|
||||
math_degrees(PyObject *module, PyObject *arg)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
double x;
|
||||
|
||||
if (!PyArg_Parse(arg, "d:degrees", &x)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = math_degrees_impl(module, x);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_radians__doc__,
|
||||
"radians($module, x, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Convert angle x from degrees to radians.");
|
||||
|
||||
#define MATH_RADIANS_METHODDEF \
|
||||
{"radians", (PyCFunction)math_radians, METH_O, math_radians__doc__},
|
||||
|
||||
static PyObject *
|
||||
math_radians_impl(PyObject *module, double x);
|
||||
|
||||
static PyObject *
|
||||
math_radians(PyObject *module, PyObject *arg)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
double x;
|
||||
|
||||
if (!PyArg_Parse(arg, "d:radians", &x)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = math_radians_impl(module, x);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_isfinite__doc__,
|
||||
"isfinite($module, x, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return True if x is neither an infinity nor a NaN, and False otherwise.");
|
||||
|
||||
#define MATH_ISFINITE_METHODDEF \
|
||||
{"isfinite", (PyCFunction)math_isfinite, METH_O, math_isfinite__doc__},
|
||||
|
||||
static PyObject *
|
||||
math_isfinite_impl(PyObject *module, double x);
|
||||
|
||||
static PyObject *
|
||||
math_isfinite(PyObject *module, PyObject *arg)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
double x;
|
||||
|
||||
if (!PyArg_Parse(arg, "d:isfinite", &x)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = math_isfinite_impl(module, x);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_isnan__doc__,
|
||||
"isnan($module, x, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return True if x is a NaN (not a number), and False otherwise.");
|
||||
|
||||
#define MATH_ISNAN_METHODDEF \
|
||||
{"isnan", (PyCFunction)math_isnan, METH_O, math_isnan__doc__},
|
||||
|
||||
static PyObject *
|
||||
math_isnan_impl(PyObject *module, double x);
|
||||
|
||||
static PyObject *
|
||||
math_isnan(PyObject *module, PyObject *arg)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
double x;
|
||||
|
||||
if (!PyArg_Parse(arg, "d:isnan", &x)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = math_isnan_impl(module, x);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_isinf__doc__,
|
||||
"isinf($module, x, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Return True if x is a positive or negative infinity, and False otherwise.");
|
||||
|
||||
#define MATH_ISINF_METHODDEF \
|
||||
{"isinf", (PyCFunction)math_isinf, METH_O, math_isinf__doc__},
|
||||
|
||||
static PyObject *
|
||||
math_isinf_impl(PyObject *module, double x);
|
||||
|
||||
static PyObject *
|
||||
math_isinf(PyObject *module, PyObject *arg)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
double x;
|
||||
|
||||
if (!PyArg_Parse(arg, "d:isinf", &x)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = math_isinf_impl(module, x);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_isclose__doc__,
|
||||
"isclose($module, /, a, b, *, rel_tol=1e-09, abs_tol=0.0)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Determine whether two floating point numbers are close in value.\n"
|
||||
"\n"
|
||||
" rel_tol\n"
|
||||
" maximum difference for being considered \"close\", relative to the\n"
|
||||
" magnitude of the input values\n"
|
||||
" abs_tol\n"
|
||||
" maximum difference for being considered \"close\", regardless of the\n"
|
||||
" magnitude of the input values\n"
|
||||
"\n"
|
||||
"Return True if a is close in value to b, and False otherwise.\n"
|
||||
"\n"
|
||||
"For the values to be considered close, the difference between them\n"
|
||||
"must be smaller than at least one of the tolerances.\n"
|
||||
"\n"
|
||||
"-inf, inf and NaN behave similarly to the IEEE 754 Standard. That\n"
|
||||
"is, NaN is not close to anything, even itself. inf and -inf are\n"
|
||||
"only close to themselves.");
|
||||
|
||||
#define MATH_ISCLOSE_METHODDEF \
|
||||
{"isclose", (PyCFunction)math_isclose, METH_FASTCALL, math_isclose__doc__},
|
||||
|
||||
static int
|
||||
math_isclose_impl(PyObject *module, double a, double b, double rel_tol,
|
||||
double abs_tol);
|
||||
|
||||
static PyObject *
|
||||
math_isclose(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
static const char * const _keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL};
|
||||
static _PyArg_Parser _parser = {"dd|$dd:isclose", _keywords, 0};
|
||||
double a;
|
||||
double b;
|
||||
double rel_tol = 1e-09;
|
||||
double abs_tol = 0.0;
|
||||
int _return_value;
|
||||
|
||||
if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
|
||||
&a, &b, &rel_tol, &abs_tol)) {
|
||||
goto exit;
|
||||
}
|
||||
_return_value = math_isclose_impl(module, a, b, rel_tol, abs_tol);
|
||||
if ((_return_value == -1) && PyErr_Occurred()) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = PyBool_FromLong((long)_return_value);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
/*[clinic end generated code: output=71806f73a5c4bf0b input=a9049054013a1b77]*/
|
|
@ -55,6 +55,14 @@ raised for division by zero and mod by zero.
|
|||
#include "Python.h"
|
||||
#include "_math.h"
|
||||
|
||||
#include "clinic/mathmodule.c.h"
|
||||
|
||||
/*[clinic input]
|
||||
module math
|
||||
[clinic start generated code]*/
|
||||
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=76bc7002685dd942]*/
|
||||
|
||||
|
||||
/*
|
||||
sin(pi*x), giving accurate results for all finite x (especially x
|
||||
integral or close to an integer). This is here for use in the
|
||||
|
@ -684,13 +692,21 @@ m_log10(double x)
|
|||
}
|
||||
|
||||
|
||||
static PyObject *
|
||||
math_gcd(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *a, *b, *g;
|
||||
/*[clinic input]
|
||||
math.gcd
|
||||
|
||||
if (!PyArg_ParseTuple(args, "OO:gcd", &a, &b))
|
||||
return NULL;
|
||||
x as a: object
|
||||
y as b: object
|
||||
/
|
||||
|
||||
greatest common divisor of x and y
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
math_gcd_impl(PyObject *module, PyObject *a, PyObject *b)
|
||||
/*[clinic end generated code: output=7b2e0c151bd7a5d8 input=c2691e57fb2a98fa]*/
|
||||
{
|
||||
PyObject *g;
|
||||
|
||||
a = PyNumber_Index(a);
|
||||
if (a == NULL)
|
||||
|
@ -706,10 +722,6 @@ math_gcd(PyObject *self, PyObject *args)
|
|||
return g;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_gcd_doc,
|
||||
"gcd(x, y) -> int\n\
|
||||
greatest common divisor of x and y");
|
||||
|
||||
|
||||
/* Call is_error when errno != 0, and where x is the result libm
|
||||
* returned. is_error will usually set up an exception and return
|
||||
|
@ -753,7 +765,7 @@ is_error(double x)
|
|||
|
||||
/*
|
||||
math_1 is used to wrap a libm function f that takes a double
|
||||
arguments and returns a double.
|
||||
argument and returns a double.
|
||||
|
||||
The error reporting follows these rules, which are designed to do
|
||||
the right thing on C89/C99 platforms and IEEE 754/non IEEE 754
|
||||
|
@ -926,22 +938,43 @@ math_2(PyObject *args, double (*func) (double, double), const char *funcname)
|
|||
PyDoc_STRVAR(math_##funcname##_doc, docstring);
|
||||
|
||||
FUNC1(acos, acos, 0,
|
||||
"acos(x)\n\nReturn the arc cosine (measured in radians) of x.")
|
||||
"acos($module, x, /)\n--\n\n"
|
||||
"Return the arc cosine (measured in radians) of x.")
|
||||
FUNC1(acosh, m_acosh, 0,
|
||||
"acosh(x)\n\nReturn the inverse hyperbolic cosine of x.")
|
||||
"acosh($module, x, /)\n--\n\n"
|
||||
"Return the inverse hyperbolic cosine of x.")
|
||||
FUNC1(asin, asin, 0,
|
||||
"asin(x)\n\nReturn the arc sine (measured in radians) of x.")
|
||||
"asin($module, x, /)\n--\n\n"
|
||||
"Return the arc sine (measured in radians) of x.")
|
||||
FUNC1(asinh, m_asinh, 0,
|
||||
"asinh(x)\n\nReturn the inverse hyperbolic sine of x.")
|
||||
"asinh($module, x, /)\n--\n\n"
|
||||
"Return the inverse hyperbolic sine of x.")
|
||||
FUNC1(atan, atan, 0,
|
||||
"atan(x)\n\nReturn the arc tangent (measured in radians) of x.")
|
||||
"atan($module, x, /)\n--\n\n"
|
||||
"Return the arc tangent (measured in radians) of x.")
|
||||
FUNC2(atan2, m_atan2,
|
||||
"atan2(y, x)\n\nReturn the arc tangent (measured in radians) of y/x.\n"
|
||||
"atan2($module, y, x, /)\n--\n\n"
|
||||
"Return the arc tangent (measured in radians) of y/x.\n\n"
|
||||
"Unlike atan(y/x), the signs of both x and y are considered.")
|
||||
FUNC1(atanh, m_atanh, 0,
|
||||
"atanh(x)\n\nReturn the inverse hyperbolic tangent of x.")
|
||||
"atanh($module, x, /)\n--\n\n"
|
||||
"Return the inverse hyperbolic tangent of x.")
|
||||
|
||||
static PyObject * math_ceil(PyObject *self, PyObject *number) {
|
||||
/*[clinic input]
|
||||
math.ceil
|
||||
|
||||
x as number: object
|
||||
/
|
||||
|
||||
Return the ceiling of x as an Integral.
|
||||
|
||||
This is the smallest integer >= x.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
math_ceil(PyObject *module, PyObject *number)
|
||||
/*[clinic end generated code: output=6c3b8a78bc201c67 input=2725352806399cab]*/
|
||||
{
|
||||
_Py_IDENTIFIER(__ceil__);
|
||||
PyObject *method, *result;
|
||||
|
||||
|
@ -956,32 +989,50 @@ static PyObject * math_ceil(PyObject *self, PyObject *number) {
|
|||
return result;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_ceil_doc,
|
||||
"ceil(x)\n\nReturn the ceiling of x as an Integral.\n"
|
||||
"This is the smallest integer >= x.");
|
||||
|
||||
FUNC2(copysign, copysign,
|
||||
"copysign(x, y)\n\nReturn a float with the magnitude (absolute value) "
|
||||
"of x but the sign \nof y. On platforms that support signed zeros, "
|
||||
"copysign(1.0, -0.0) \nreturns -1.0.\n")
|
||||
"copysign($module, x, y, /)\n--\n\n"
|
||||
"Return a float with the magnitude (absolute value) of x but the sign of y.\n\n"
|
||||
"On platforms that support signed zeros, copysign(1.0, -0.0)\n"
|
||||
"returns -1.0.\n")
|
||||
FUNC1(cos, cos, 0,
|
||||
"cos(x)\n\nReturn the cosine of x (measured in radians).")
|
||||
"cos($module, x, /)\n--\n\n"
|
||||
"Return the cosine of x (measured in radians).")
|
||||
FUNC1(cosh, cosh, 1,
|
||||
"cosh(x)\n\nReturn the hyperbolic cosine of x.")
|
||||
"cosh($module, x, /)\n--\n\n"
|
||||
"Return the hyperbolic cosine of x.")
|
||||
FUNC1A(erf, m_erf,
|
||||
"erf(x)\n\nError function at x.")
|
||||
"erf($module, x, /)\n--\n\n"
|
||||
"Error function at x.")
|
||||
FUNC1A(erfc, m_erfc,
|
||||
"erfc(x)\n\nComplementary error function at x.")
|
||||
"erfc($module, x, /)\n--\n\n"
|
||||
"Complementary error function at x.")
|
||||
FUNC1(exp, exp, 1,
|
||||
"exp(x)\n\nReturn e raised to the power of x.")
|
||||
"exp($module, x, /)\n--\n\n"
|
||||
"Return e raised to the power of x.")
|
||||
FUNC1(expm1, m_expm1, 1,
|
||||
"expm1(x)\n\nReturn exp(x)-1.\n"
|
||||
"expm1($module, x, /)\n--\n\n"
|
||||
"Return exp(x)-1.\n\n"
|
||||
"This function avoids the loss of precision involved in the direct "
|
||||
"evaluation of exp(x)-1 for small x.")
|
||||
FUNC1(fabs, fabs, 0,
|
||||
"fabs(x)\n\nReturn the absolute value of the float x.")
|
||||
"fabs($module, x, /)\n--\n\n"
|
||||
"Return the absolute value of the float x.")
|
||||
|
||||
static PyObject * math_floor(PyObject *self, PyObject *number) {
|
||||
/*[clinic input]
|
||||
math.floor
|
||||
|
||||
x as number: object
|
||||
/
|
||||
|
||||
Return the floor of x as an Integral.
|
||||
|
||||
This is the largest integer <= x.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
math_floor(PyObject *module, PyObject *number)
|
||||
/*[clinic end generated code: output=c6a65c4884884b8a input=63af6b5d7ebcc3d6]*/
|
||||
{
|
||||
_Py_IDENTIFIER(__floor__);
|
||||
PyObject *method, *result;
|
||||
|
||||
|
@ -996,27 +1047,31 @@ static PyObject * math_floor(PyObject *self, PyObject *number) {
|
|||
return result;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_floor_doc,
|
||||
"floor(x)\n\nReturn the floor of x as an Integral.\n"
|
||||
"This is the largest integer <= x.");
|
||||
|
||||
FUNC1A(gamma, m_tgamma,
|
||||
"gamma(x)\n\nGamma function at x.")
|
||||
"gamma($module, x, /)\n--\n\n"
|
||||
"Gamma function at x.")
|
||||
FUNC1A(lgamma, m_lgamma,
|
||||
"lgamma(x)\n\nNatural logarithm of absolute value of Gamma function at x.")
|
||||
"lgamma($module, x, /)\n--\n\n"
|
||||
"Natural logarithm of absolute value of Gamma function at x.")
|
||||
FUNC1(log1p, m_log1p, 0,
|
||||
"log1p(x)\n\nReturn the natural logarithm of 1+x (base e).\n"
|
||||
"log1p($module, x, /)\n--\n\n"
|
||||
"Return the natural logarithm of 1+x (base e).\n\n"
|
||||
"The result is computed in a way which is accurate for x near zero.")
|
||||
FUNC1(sin, sin, 0,
|
||||
"sin(x)\n\nReturn the sine of x (measured in radians).")
|
||||
"sin($module, x, /)\n--\n\n"
|
||||
"Return the sine of x (measured in radians).")
|
||||
FUNC1(sinh, sinh, 1,
|
||||
"sinh(x)\n\nReturn the hyperbolic sine of x.")
|
||||
"sinh($module, x, /)\n--\n\n"
|
||||
"Return the hyperbolic sine of x.")
|
||||
FUNC1(sqrt, sqrt, 0,
|
||||
"sqrt(x)\n\nReturn the square root of x.")
|
||||
"sqrt($module, x, /)\n--\n\n"
|
||||
"Return the square root of x.")
|
||||
FUNC1(tan, tan, 0,
|
||||
"tan(x)\n\nReturn the tangent of x (measured in radians).")
|
||||
"tan($module, x, /)\n--\n\n"
|
||||
"Return the tangent of x (measured in radians).")
|
||||
FUNC1(tanh, tanh, 0,
|
||||
"tanh(x)\n\nReturn the hyperbolic tangent of x.")
|
||||
"tanh($module, x, /)\n--\n\n"
|
||||
"Return the hyperbolic tangent of x.")
|
||||
|
||||
/* Precision summation function as msum() by Raymond Hettinger in
|
||||
<http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/393090>,
|
||||
|
@ -1114,8 +1169,20 @@ _fsum_realloc(double **p_ptr, Py_ssize_t n,
|
|||
Depends on IEEE 754 arithmetic guarantees and half-even rounding.
|
||||
*/
|
||||
|
||||
/*[clinic input]
|
||||
math.fsum
|
||||
|
||||
seq: object
|
||||
/
|
||||
|
||||
Return an accurate floating point sum of values in the iterable seq.
|
||||
|
||||
Assumes IEEE-754 floating point arithmetic.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
math_fsum(PyObject *self, PyObject *seq)
|
||||
math_fsum(PyObject *module, PyObject *seq)
|
||||
/*[clinic end generated code: output=ba5c672b87fe34fc input=c51b7d8caf6f6e82]*/
|
||||
{
|
||||
PyObject *item, *iter, *sum = NULL;
|
||||
Py_ssize_t i, j, n = 0, m = NUM_PARTIALS;
|
||||
|
@ -1234,10 +1301,6 @@ _fsum_error:
|
|||
|
||||
#undef NUM_PARTIALS
|
||||
|
||||
PyDoc_STRVAR(math_fsum_doc,
|
||||
"fsum(iterable)\n\n\
|
||||
Return an accurate floating point sum of values in the iterable.\n\
|
||||
Assumes IEEE-754 floating point arithmetic.");
|
||||
|
||||
/* Return the smallest integer k such that n < 2**k, or 0 if n == 0.
|
||||
* Equivalent to floor(lg(x))+1. Also equivalent to: bitwidth_of_type -
|
||||
|
@ -1447,6 +1510,7 @@ factorial_odd_part(unsigned long n)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Lookup table for small factorial values */
|
||||
|
||||
static const unsigned long SmallFactorials[] = {
|
||||
|
@ -1459,8 +1523,20 @@ static const unsigned long SmallFactorials[] = {
|
|||
#endif
|
||||
};
|
||||
|
||||
/*[clinic input]
|
||||
math.factorial
|
||||
|
||||
x as arg: object
|
||||
/
|
||||
|
||||
Find x!.
|
||||
|
||||
Raise a ValueError if x is negative or non-integral.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
math_factorial(PyObject *self, PyObject *arg)
|
||||
math_factorial(PyObject *module, PyObject *arg)
|
||||
/*[clinic end generated code: output=6686f26fae00e9ca input=6d1c8105c0d91fb4]*/
|
||||
{
|
||||
long x;
|
||||
int overflow;
|
||||
|
@ -1518,28 +1594,36 @@ math_factorial(PyObject *self, PyObject *arg)
|
|||
return result;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_factorial_doc,
|
||||
"factorial(x) -> Integral\n"
|
||||
"\n"
|
||||
"Find x!. Raise a ValueError if x is negative or non-integral.");
|
||||
|
||||
/*[clinic input]
|
||||
math.trunc
|
||||
|
||||
x: object
|
||||
/
|
||||
|
||||
Truncates the Real x to the nearest Integral toward 0.
|
||||
|
||||
Uses the __trunc__ magic method.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
math_trunc(PyObject *self, PyObject *number)
|
||||
math_trunc(PyObject *module, PyObject *x)
|
||||
/*[clinic end generated code: output=34b9697b707e1031 input=2168b34e0a09134d]*/
|
||||
{
|
||||
_Py_IDENTIFIER(__trunc__);
|
||||
PyObject *trunc, *result;
|
||||
|
||||
if (Py_TYPE(number)->tp_dict == NULL) {
|
||||
if (PyType_Ready(Py_TYPE(number)) < 0)
|
||||
if (Py_TYPE(x)->tp_dict == NULL) {
|
||||
if (PyType_Ready(Py_TYPE(x)) < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
trunc = _PyObject_LookupSpecial(number, &PyId___trunc__);
|
||||
trunc = _PyObject_LookupSpecial(x, &PyId___trunc__);
|
||||
if (trunc == NULL) {
|
||||
if (!PyErr_Occurred())
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"type %.100s doesn't define __trunc__ method",
|
||||
Py_TYPE(number)->tp_name);
|
||||
Py_TYPE(x)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
result = _PyObject_CallNoArg(trunc);
|
||||
|
@ -1547,18 +1631,24 @@ math_trunc(PyObject *self, PyObject *number)
|
|||
return result;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_trunc_doc,
|
||||
"trunc(x:Real) -> Integral\n"
|
||||
"\n"
|
||||
"Truncates x to the nearest Integral toward 0. Uses the __trunc__ magic method.");
|
||||
|
||||
/*[clinic input]
|
||||
math.frexp
|
||||
|
||||
x: double
|
||||
/
|
||||
|
||||
Return the mantissa and exponent of x, as pair (m, e).
|
||||
|
||||
m is a float and e is an int, such that x = m * 2.**e.
|
||||
If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
math_frexp(PyObject *self, PyObject *arg)
|
||||
math_frexp_impl(PyObject *module, double x)
|
||||
/*[clinic end generated code: output=03e30d252a15ad4a input=96251c9e208bc6e9]*/
|
||||
{
|
||||
int i;
|
||||
double x = PyFloat_AsDouble(arg);
|
||||
if (x == -1.0 && PyErr_Occurred())
|
||||
return NULL;
|
||||
/* deal with special cases directly, to sidestep platform
|
||||
differences */
|
||||
if (Py_IS_NAN(x) || Py_IS_INFINITY(x) || !x) {
|
||||
|
@ -1572,27 +1662,31 @@ math_frexp(PyObject *self, PyObject *arg)
|
|||
return Py_BuildValue("(di)", x, i);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_frexp_doc,
|
||||
"frexp(x)\n"
|
||||
"\n"
|
||||
"Return the mantissa and exponent of x, as pair (m, e).\n"
|
||||
"m is a float and e is an int, such that x = m * 2.**e.\n"
|
||||
"If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0.");
|
||||
|
||||
/*[clinic input]
|
||||
math.ldexp
|
||||
|
||||
x: double
|
||||
i: object
|
||||
/
|
||||
|
||||
Return x * (2**i).
|
||||
|
||||
This is essentially the inverse of frexp().
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
math_ldexp(PyObject *self, PyObject *args)
|
||||
math_ldexp_impl(PyObject *module, double x, PyObject *i)
|
||||
/*[clinic end generated code: output=b6892f3c2df9cc6a input=17d5970c1a40a8c1]*/
|
||||
{
|
||||
double x, r;
|
||||
PyObject *oexp;
|
||||
double r;
|
||||
long exp;
|
||||
int overflow;
|
||||
if (! PyArg_ParseTuple(args, "dO:ldexp", &x, &oexp))
|
||||
return NULL;
|
||||
|
||||
if (PyLong_Check(oexp)) {
|
||||
if (PyLong_Check(i)) {
|
||||
/* on overflow, replace exponent with either LONG_MAX
|
||||
or LONG_MIN, depending on the sign. */
|
||||
exp = PyLong_AsLongAndOverflow(oexp, &overflow);
|
||||
exp = PyLong_AsLongAndOverflow(i, &overflow);
|
||||
if (exp == -1 && PyErr_Occurred())
|
||||
return NULL;
|
||||
if (overflow)
|
||||
|
@ -1630,16 +1724,23 @@ math_ldexp(PyObject *self, PyObject *args)
|
|||
return PyFloat_FromDouble(r);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_ldexp_doc,
|
||||
"ldexp(x, i)\n\n\
|
||||
Return x * (2**i).");
|
||||
|
||||
/*[clinic input]
|
||||
math.modf
|
||||
|
||||
x: double
|
||||
/
|
||||
|
||||
Return the fractional and integer parts of x.
|
||||
|
||||
Both results carry the sign of x and are floats.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
math_modf(PyObject *self, PyObject *arg)
|
||||
math_modf_impl(PyObject *module, double x)
|
||||
/*[clinic end generated code: output=90cee0260014c3c0 input=b4cfb6786afd9035]*/
|
||||
{
|
||||
double y, x = PyFloat_AsDouble(arg);
|
||||
if (x == -1.0 && PyErr_Occurred())
|
||||
return NULL;
|
||||
double y;
|
||||
/* some platforms don't do the right thing for NaNs and
|
||||
infinities, so we take care of special cases directly. */
|
||||
if (!Py_IS_FINITE(x)) {
|
||||
|
@ -1656,11 +1757,6 @@ math_modf(PyObject *self, PyObject *arg)
|
|||
return Py_BuildValue("(dd)", x, y);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_modf_doc,
|
||||
"modf(x)\n"
|
||||
"\n"
|
||||
"Return the fractional and integer parts of x. Both results carry the sign\n"
|
||||
"of x and are floats.");
|
||||
|
||||
/* A decent logarithm is easy to compute even for huge ints, but libm can't
|
||||
do that by itself -- loghelper can. func is log or log10, and name is
|
||||
|
@ -1709,18 +1805,30 @@ loghelper(PyObject* arg, double (*func)(double), const char *funcname)
|
|||
return math_1(arg, func, 0);
|
||||
}
|
||||
|
||||
|
||||
/*[clinic input]
|
||||
math.log
|
||||
|
||||
x: object
|
||||
[
|
||||
base: object(c_default="NULL") = math.e
|
||||
]
|
||||
/
|
||||
|
||||
Return the logarithm of x to the given base.
|
||||
|
||||
If the base not specified, returns the natural logarithm (base e) of x.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
math_log(PyObject *self, PyObject *args)
|
||||
math_log_impl(PyObject *module, PyObject *x, int group_right_1,
|
||||
PyObject *base)
|
||||
/*[clinic end generated code: output=7b5a39e526b73fc9 input=0f62d5726cbfebbd]*/
|
||||
{
|
||||
PyObject *arg;
|
||||
PyObject *base = NULL;
|
||||
PyObject *num, *den;
|
||||
PyObject *ans;
|
||||
|
||||
if (!PyArg_UnpackTuple(args, "log", 1, 2, &arg, &base))
|
||||
return NULL;
|
||||
|
||||
num = loghelper(arg, m_log, "log");
|
||||
num = loghelper(x, m_log, "log");
|
||||
if (num == NULL || base == NULL)
|
||||
return num;
|
||||
|
||||
|
@ -1736,40 +1844,58 @@ math_log(PyObject *self, PyObject *args)
|
|||
return ans;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_log_doc,
|
||||
"log(x[, base])\n\n\
|
||||
Return the logarithm of x to the given base.\n\
|
||||
If the base not specified, returns the natural logarithm (base e) of x.");
|
||||
|
||||
/*[clinic input]
|
||||
math.log2
|
||||
|
||||
x: object
|
||||
/
|
||||
|
||||
Return the base 2 logarithm of x.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
math_log2(PyObject *self, PyObject *arg)
|
||||
math_log2(PyObject *module, PyObject *x)
|
||||
/*[clinic end generated code: output=5425899a4d5d6acb input=08321262bae4f39b]*/
|
||||
{
|
||||
return loghelper(arg, m_log2, "log2");
|
||||
return loghelper(x, m_log2, "log2");
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_log2_doc,
|
||||
"log2(x)\n\nReturn the base 2 logarithm of x.");
|
||||
|
||||
/*[clinic input]
|
||||
math.log10
|
||||
|
||||
x: object
|
||||
/
|
||||
|
||||
Return the base 10 logarithm of x.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
math_log10(PyObject *self, PyObject *arg)
|
||||
math_log10(PyObject *module, PyObject *x)
|
||||
/*[clinic end generated code: output=be72a64617df9c6f input=b2469d02c6469e53]*/
|
||||
{
|
||||
return loghelper(arg, m_log10, "log10");
|
||||
return loghelper(x, m_log10, "log10");
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_log10_doc,
|
||||
"log10(x)\n\nReturn the base 10 logarithm of x.");
|
||||
|
||||
/*[clinic input]
|
||||
math.fmod
|
||||
|
||||
x: double
|
||||
y: double
|
||||
/
|
||||
|
||||
Return fmod(x, y), according to platform C.
|
||||
|
||||
x % y may differ.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
math_fmod(PyObject *self, PyObject *args)
|
||||
math_fmod_impl(PyObject *module, double x, double y)
|
||||
/*[clinic end generated code: output=7559d794343a27b5 input=4f84caa8cfc26a03]*/
|
||||
{
|
||||
PyObject *ox, *oy;
|
||||
double r, x, y;
|
||||
if (! PyArg_UnpackTuple(args, "fmod", 2, 2, &ox, &oy))
|
||||
return NULL;
|
||||
x = PyFloat_AsDouble(ox);
|
||||
y = PyFloat_AsDouble(oy);
|
||||
if ((x == -1.0 || y == -1.0) && PyErr_Occurred())
|
||||
return NULL;
|
||||
double r;
|
||||
/* fmod(x, +/-Inf) returns x for finite x. */
|
||||
if (Py_IS_INFINITY(y) && Py_IS_FINITE(x))
|
||||
return PyFloat_FromDouble(x);
|
||||
|
@ -1789,21 +1915,22 @@ math_fmod(PyObject *self, PyObject *args)
|
|||
return PyFloat_FromDouble(r);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_fmod_doc,
|
||||
"fmod(x, y)\n\nReturn fmod(x, y), according to platform C."
|
||||
" x % y may differ.");
|
||||
|
||||
/*[clinic input]
|
||||
math.hypot
|
||||
|
||||
x: double
|
||||
y: double
|
||||
/
|
||||
|
||||
Return the Euclidean distance, sqrt(x*x + y*y).
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
math_hypot(PyObject *self, PyObject *args)
|
||||
math_hypot_impl(PyObject *module, double x, double y)
|
||||
/*[clinic end generated code: output=b7686e5be468ef87 input=7f8eea70406474aa]*/
|
||||
{
|
||||
PyObject *ox, *oy;
|
||||
double r, x, y;
|
||||
if (! PyArg_UnpackTuple(args, "hypot", 2, 2, &ox, &oy))
|
||||
return NULL;
|
||||
x = PyFloat_AsDouble(ox);
|
||||
y = PyFloat_AsDouble(oy);
|
||||
if ((x == -1.0 || y == -1.0) && PyErr_Occurred())
|
||||
return NULL;
|
||||
double r;
|
||||
/* hypot(x, +/-Inf) returns Inf, even if x is a NaN. */
|
||||
if (Py_IS_INFINITY(x))
|
||||
return PyFloat_FromDouble(fabs(x));
|
||||
|
@ -1831,8 +1958,6 @@ math_hypot(PyObject *self, PyObject *args)
|
|||
return PyFloat_FromDouble(r);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_hypot_doc,
|
||||
"hypot(x, y)\n\nReturn the Euclidean distance, sqrt(x*x + y*y).");
|
||||
|
||||
/* pow can't use math_2, but needs its own wrapper: the problem is
|
||||
that an infinite result can arise either as a result of overflow
|
||||
|
@ -1840,19 +1965,22 @@ PyDoc_STRVAR(math_hypot_doc,
|
|||
e.g. 0.**-5. (for which ValueError needs to be raised.)
|
||||
*/
|
||||
|
||||
static PyObject *
|
||||
math_pow(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *ox, *oy;
|
||||
double r, x, y;
|
||||
int odd_y;
|
||||
/*[clinic input]
|
||||
math.pow
|
||||
|
||||
if (! PyArg_UnpackTuple(args, "pow", 2, 2, &ox, &oy))
|
||||
return NULL;
|
||||
x = PyFloat_AsDouble(ox);
|
||||
y = PyFloat_AsDouble(oy);
|
||||
if ((x == -1.0 || y == -1.0) && PyErr_Occurred())
|
||||
return NULL;
|
||||
x: double
|
||||
y: double
|
||||
/
|
||||
|
||||
Return x**y (x to the power of y).
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
math_pow_impl(PyObject *module, double x, double y)
|
||||
/*[clinic end generated code: output=fff93e65abccd6b0 input=c26f1f6075088bfd]*/
|
||||
{
|
||||
double r;
|
||||
int odd_y;
|
||||
|
||||
/* deal directly with IEEE specials, to cope with problems on various
|
||||
platforms whose semantics don't exactly match C99 */
|
||||
|
@ -1918,107 +2046,139 @@ math_pow(PyObject *self, PyObject *args)
|
|||
return PyFloat_FromDouble(r);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_pow_doc,
|
||||
"pow(x, y)\n\nReturn x**y (x to the power of y).");
|
||||
|
||||
static const double degToRad = Py_MATH_PI / 180.0;
|
||||
static const double radToDeg = 180.0 / Py_MATH_PI;
|
||||
|
||||
/*[clinic input]
|
||||
math.degrees
|
||||
|
||||
x: double
|
||||
/
|
||||
|
||||
Convert angle x from radians to degrees.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
math_degrees(PyObject *self, PyObject *arg)
|
||||
math_degrees_impl(PyObject *module, double x)
|
||||
/*[clinic end generated code: output=7fea78b294acd12f input=81e016555d6e3660]*/
|
||||
{
|
||||
double x = PyFloat_AsDouble(arg);
|
||||
if (x == -1.0 && PyErr_Occurred())
|
||||
return NULL;
|
||||
return PyFloat_FromDouble(x * radToDeg);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_degrees_doc,
|
||||
"degrees(x)\n\n\
|
||||
Convert angle x from radians to degrees.");
|
||||
|
||||
/*[clinic input]
|
||||
math.radians
|
||||
|
||||
x: double
|
||||
/
|
||||
|
||||
Convert angle x from degrees to radians.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
math_radians(PyObject *self, PyObject *arg)
|
||||
math_radians_impl(PyObject *module, double x)
|
||||
/*[clinic end generated code: output=34daa47caf9b1590 input=91626fc489fe3d63]*/
|
||||
{
|
||||
double x = PyFloat_AsDouble(arg);
|
||||
if (x == -1.0 && PyErr_Occurred())
|
||||
return NULL;
|
||||
return PyFloat_FromDouble(x * degToRad);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_radians_doc,
|
||||
"radians(x)\n\n\
|
||||
Convert angle x from degrees to radians.");
|
||||
|
||||
/*[clinic input]
|
||||
math.isfinite
|
||||
|
||||
x: double
|
||||
/
|
||||
|
||||
Return True if x is neither an infinity nor a NaN, and False otherwise.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
math_isfinite(PyObject *self, PyObject *arg)
|
||||
math_isfinite_impl(PyObject *module, double x)
|
||||
/*[clinic end generated code: output=8ba1f396440c9901 input=46967d254812e54a]*/
|
||||
{
|
||||
double x = PyFloat_AsDouble(arg);
|
||||
if (x == -1.0 && PyErr_Occurred())
|
||||
return NULL;
|
||||
return PyBool_FromLong((long)Py_IS_FINITE(x));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_isfinite_doc,
|
||||
"isfinite(x) -> bool\n\n\
|
||||
Return True if x is neither an infinity nor a NaN, and False otherwise.");
|
||||
|
||||
/*[clinic input]
|
||||
math.isnan
|
||||
|
||||
x: double
|
||||
/
|
||||
|
||||
Return True if x is a NaN (not a number), and False otherwise.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
math_isnan(PyObject *self, PyObject *arg)
|
||||
math_isnan_impl(PyObject *module, double x)
|
||||
/*[clinic end generated code: output=f537b4d6df878c3e input=935891e66083f46a]*/
|
||||
{
|
||||
double x = PyFloat_AsDouble(arg);
|
||||
if (x == -1.0 && PyErr_Occurred())
|
||||
return NULL;
|
||||
return PyBool_FromLong((long)Py_IS_NAN(x));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_isnan_doc,
|
||||
"isnan(x) -> bool\n\n\
|
||||
Return True if x is a NaN (not a number), and False otherwise.");
|
||||
|
||||
/*[clinic input]
|
||||
math.isinf
|
||||
|
||||
x: double
|
||||
/
|
||||
|
||||
Return True if x is a positive or negative infinity, and False otherwise.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
math_isinf(PyObject *self, PyObject *arg)
|
||||
math_isinf_impl(PyObject *module, double x)
|
||||
/*[clinic end generated code: output=9f00cbec4de7b06b input=32630e4212cf961f]*/
|
||||
{
|
||||
double x = PyFloat_AsDouble(arg);
|
||||
if (x == -1.0 && PyErr_Occurred())
|
||||
return NULL;
|
||||
return PyBool_FromLong((long)Py_IS_INFINITY(x));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_isinf_doc,
|
||||
"isinf(x) -> bool\n\n\
|
||||
Return True if x is a positive or negative infinity, and False otherwise.");
|
||||
|
||||
static PyObject *
|
||||
math_isclose(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||
/*[clinic input]
|
||||
math.isclose -> bool
|
||||
|
||||
a: double
|
||||
b: double
|
||||
*
|
||||
rel_tol: double = 1e-09
|
||||
maximum difference for being considered "close", relative to the
|
||||
magnitude of the input values
|
||||
abs_tol: double = 0.0
|
||||
maximum difference for being considered "close", regardless of the
|
||||
magnitude of the input values
|
||||
|
||||
Determine whether two floating point numbers are close in value.
|
||||
|
||||
Return True if a is close in value to b, and False otherwise.
|
||||
|
||||
For the values to be considered close, the difference between them
|
||||
must be smaller than at least one of the tolerances.
|
||||
|
||||
-inf, inf and NaN behave similarly to the IEEE 754 Standard. That
|
||||
is, NaN is not close to anything, even itself. inf and -inf are
|
||||
only close to themselves.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static int
|
||||
math_isclose_impl(PyObject *module, double a, double b, double rel_tol,
|
||||
double abs_tol)
|
||||
/*[clinic end generated code: output=b73070207511952d input=f28671871ea5bfba]*/
|
||||
{
|
||||
double a, b;
|
||||
double rel_tol = 1e-9;
|
||||
double abs_tol = 0.0;
|
||||
double diff = 0.0;
|
||||
long result = 0;
|
||||
|
||||
static char *keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL};
|
||||
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "dd|$dd:isclose",
|
||||
keywords,
|
||||
&a, &b, &rel_tol, &abs_tol
|
||||
))
|
||||
return NULL;
|
||||
|
||||
/* sanity check on the inputs */
|
||||
if (rel_tol < 0.0 || abs_tol < 0.0 ) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"tolerances must be non-negative");
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( a == b ) {
|
||||
/* short circuit exact equality -- needed to catch two infinities of
|
||||
the same sign. And perhaps speeds things up a bit sometimes.
|
||||
*/
|
||||
Py_RETURN_TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* This catches the case of two infinities of opposite sign, or
|
||||
|
@ -2029,7 +2189,7 @@ math_isclose(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
*/
|
||||
|
||||
if (Py_IS_INFINITY(a) || Py_IS_INFINITY(b)) {
|
||||
Py_RETURN_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* now do the regular computation
|
||||
|
@ -2038,33 +2198,11 @@ math_isclose(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
|
||||
diff = fabs(b - a);
|
||||
|
||||
result = (((diff <= fabs(rel_tol * b)) ||
|
||||
return (((diff <= fabs(rel_tol * b)) ||
|
||||
(diff <= fabs(rel_tol * a))) ||
|
||||
(diff <= abs_tol));
|
||||
|
||||
return PyBool_FromLong(result);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(math_isclose_doc,
|
||||
"isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0) -> bool\n"
|
||||
"\n"
|
||||
"Determine whether two floating point numbers are close in value.\n"
|
||||
"\n"
|
||||
" rel_tol\n"
|
||||
" maximum difference for being considered \"close\", relative to the\n"
|
||||
" magnitude of the input values\n"
|
||||
" abs_tol\n"
|
||||
" maximum difference for being considered \"close\", regardless of the\n"
|
||||
" magnitude of the input values\n"
|
||||
"\n"
|
||||
"Return True if a is close in value to b, and False otherwise.\n"
|
||||
"\n"
|
||||
"For the values to be considered close, the difference between them\n"
|
||||
"must be smaller than at least one of the tolerances.\n"
|
||||
"\n"
|
||||
"-inf, inf and NaN behave similarly to the IEEE 754 Standard. That\n"
|
||||
"is, NaN is not close to anything, even itself. inf and -inf are\n"
|
||||
"only close to themselves.");
|
||||
|
||||
static PyMethodDef math_methods[] = {
|
||||
{"acos", math_acos, METH_O, math_acos_doc},
|
||||
|
@ -2074,44 +2212,43 @@ static PyMethodDef math_methods[] = {
|
|||
{"atan", math_atan, METH_O, math_atan_doc},
|
||||
{"atan2", math_atan2, METH_VARARGS, math_atan2_doc},
|
||||
{"atanh", math_atanh, METH_O, math_atanh_doc},
|
||||
{"ceil", math_ceil, METH_O, math_ceil_doc},
|
||||
MATH_CEIL_METHODDEF
|
||||
{"copysign", math_copysign, METH_VARARGS, math_copysign_doc},
|
||||
{"cos", math_cos, METH_O, math_cos_doc},
|
||||
{"cosh", math_cosh, METH_O, math_cosh_doc},
|
||||
{"degrees", math_degrees, METH_O, math_degrees_doc},
|
||||
MATH_DEGREES_METHODDEF
|
||||
{"erf", math_erf, METH_O, math_erf_doc},
|
||||
{"erfc", math_erfc, METH_O, math_erfc_doc},
|
||||
{"exp", math_exp, METH_O, math_exp_doc},
|
||||
{"expm1", math_expm1, METH_O, math_expm1_doc},
|
||||
{"fabs", math_fabs, METH_O, math_fabs_doc},
|
||||
{"factorial", math_factorial, METH_O, math_factorial_doc},
|
||||
{"floor", math_floor, METH_O, math_floor_doc},
|
||||
{"fmod", math_fmod, METH_VARARGS, math_fmod_doc},
|
||||
{"frexp", math_frexp, METH_O, math_frexp_doc},
|
||||
{"fsum", math_fsum, METH_O, math_fsum_doc},
|
||||
MATH_FACTORIAL_METHODDEF
|
||||
MATH_FLOOR_METHODDEF
|
||||
MATH_FMOD_METHODDEF
|
||||
MATH_FREXP_METHODDEF
|
||||
MATH_FSUM_METHODDEF
|
||||
{"gamma", math_gamma, METH_O, math_gamma_doc},
|
||||
{"gcd", math_gcd, METH_VARARGS, math_gcd_doc},
|
||||
{"hypot", math_hypot, METH_VARARGS, math_hypot_doc},
|
||||
{"isclose", (PyCFunction) math_isclose, METH_VARARGS | METH_KEYWORDS,
|
||||
math_isclose_doc},
|
||||
{"isfinite", math_isfinite, METH_O, math_isfinite_doc},
|
||||
{"isinf", math_isinf, METH_O, math_isinf_doc},
|
||||
{"isnan", math_isnan, METH_O, math_isnan_doc},
|
||||
{"ldexp", math_ldexp, METH_VARARGS, math_ldexp_doc},
|
||||
MATH_GCD_METHODDEF
|
||||
MATH_HYPOT_METHODDEF
|
||||
MATH_ISCLOSE_METHODDEF
|
||||
MATH_ISFINITE_METHODDEF
|
||||
MATH_ISINF_METHODDEF
|
||||
MATH_ISNAN_METHODDEF
|
||||
MATH_LDEXP_METHODDEF
|
||||
{"lgamma", math_lgamma, METH_O, math_lgamma_doc},
|
||||
{"log", math_log, METH_VARARGS, math_log_doc},
|
||||
MATH_LOG_METHODDEF
|
||||
{"log1p", math_log1p, METH_O, math_log1p_doc},
|
||||
{"log10", math_log10, METH_O, math_log10_doc},
|
||||
{"log2", math_log2, METH_O, math_log2_doc},
|
||||
{"modf", math_modf, METH_O, math_modf_doc},
|
||||
{"pow", math_pow, METH_VARARGS, math_pow_doc},
|
||||
{"radians", math_radians, METH_O, math_radians_doc},
|
||||
MATH_LOG10_METHODDEF
|
||||
MATH_LOG2_METHODDEF
|
||||
MATH_MODF_METHODDEF
|
||||
MATH_POW_METHODDEF
|
||||
MATH_RADIANS_METHODDEF
|
||||
{"sin", math_sin, METH_O, math_sin_doc},
|
||||
{"sinh", math_sinh, METH_O, math_sinh_doc},
|
||||
{"sqrt", math_sqrt, METH_O, math_sqrt_doc},
|
||||
{"tan", math_tan, METH_O, math_tan_doc},
|
||||
{"tanh", math_tanh, METH_O, math_tanh_doc},
|
||||
{"trunc", math_trunc, METH_O, math_trunc_doc},
|
||||
MATH_TRUNC_METHODDEF
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue