blob: 84561b955787b76be9f1b69ca0fb000b1ac6d339 [file] [log] [blame]
Serhiy Storchakac9ea9332017-01-19 18:13:09 +02001/*[clinic input]
2preserve
3[clinic start generated code]*/
4
5PyDoc_STRVAR(math_gcd__doc__,
6"gcd($module, x, y, /)\n"
7"--\n"
8"\n"
9"greatest common divisor of x and y");
10
11#define MATH_GCD_METHODDEF \
Serhiy Storchaka4a934d42018-11-27 11:27:36 +020012 {"gcd", (PyCFunction)(void(*)(void))math_gcd, METH_FASTCALL, math_gcd__doc__},
Serhiy Storchakac9ea9332017-01-19 18:13:09 +020013
14static PyObject *
15math_gcd_impl(PyObject *module, PyObject *a, PyObject *b);
16
17static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +020018math_gcd(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
Serhiy Storchakac9ea9332017-01-19 18:13:09 +020019{
20 PyObject *return_value = NULL;
21 PyObject *a;
22 PyObject *b;
23
Serhiy Storchaka2a39d252019-01-11 18:01:42 +020024 if (!_PyArg_CheckPositional("gcd", nargs, 2, 2)) {
Serhiy Storchakac9ea9332017-01-19 18:13:09 +020025 goto exit;
26 }
Serhiy Storchaka2a39d252019-01-11 18:01:42 +020027 a = args[0];
28 b = args[1];
Serhiy Storchakac9ea9332017-01-19 18:13:09 +020029 return_value = math_gcd_impl(module, a, b);
30
31exit:
32 return return_value;
33}
34
35PyDoc_STRVAR(math_ceil__doc__,
36"ceil($module, x, /)\n"
37"--\n"
38"\n"
39"Return the ceiling of x as an Integral.\n"
40"\n"
41"This is the smallest integer >= x.");
42
43#define MATH_CEIL_METHODDEF \
44 {"ceil", (PyCFunction)math_ceil, METH_O, math_ceil__doc__},
45
46PyDoc_STRVAR(math_floor__doc__,
47"floor($module, x, /)\n"
48"--\n"
49"\n"
50"Return the floor of x as an Integral.\n"
51"\n"
52"This is the largest integer <= x.");
53
54#define MATH_FLOOR_METHODDEF \
55 {"floor", (PyCFunction)math_floor, METH_O, math_floor__doc__},
56
57PyDoc_STRVAR(math_fsum__doc__,
58"fsum($module, seq, /)\n"
59"--\n"
60"\n"
61"Return an accurate floating point sum of values in the iterable seq.\n"
62"\n"
63"Assumes IEEE-754 floating point arithmetic.");
64
65#define MATH_FSUM_METHODDEF \
66 {"fsum", (PyCFunction)math_fsum, METH_O, math_fsum__doc__},
67
Mark Dickinson73934b92019-05-18 12:29:50 +010068PyDoc_STRVAR(math_isqrt__doc__,
69"isqrt($module, n, /)\n"
70"--\n"
71"\n"
72"Return the integer part of the square root of the input.");
73
74#define MATH_ISQRT_METHODDEF \
75 {"isqrt", (PyCFunction)math_isqrt, METH_O, math_isqrt__doc__},
76
Serhiy Storchakac9ea9332017-01-19 18:13:09 +020077PyDoc_STRVAR(math_factorial__doc__,
78"factorial($module, x, /)\n"
79"--\n"
80"\n"
81"Find x!.\n"
82"\n"
83"Raise a ValueError if x is negative or non-integral.");
84
85#define MATH_FACTORIAL_METHODDEF \
86 {"factorial", (PyCFunction)math_factorial, METH_O, math_factorial__doc__},
87
88PyDoc_STRVAR(math_trunc__doc__,
89"trunc($module, x, /)\n"
90"--\n"
91"\n"
92"Truncates the Real x to the nearest Integral toward 0.\n"
93"\n"
94"Uses the __trunc__ magic method.");
95
96#define MATH_TRUNC_METHODDEF \
97 {"trunc", (PyCFunction)math_trunc, METH_O, math_trunc__doc__},
98
99PyDoc_STRVAR(math_frexp__doc__,
100"frexp($module, x, /)\n"
101"--\n"
102"\n"
103"Return the mantissa and exponent of x, as pair (m, e).\n"
104"\n"
105"m is a float and e is an int, such that x = m * 2.**e.\n"
106"If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0.");
107
108#define MATH_FREXP_METHODDEF \
109 {"frexp", (PyCFunction)math_frexp, METH_O, math_frexp__doc__},
110
111static PyObject *
112math_frexp_impl(PyObject *module, double x);
113
114static PyObject *
115math_frexp(PyObject *module, PyObject *arg)
116{
117 PyObject *return_value = NULL;
118 double x;
119
Serhiy Storchaka32d96a22018-12-25 13:23:47 +0200120 x = PyFloat_AsDouble(arg);
121 if (PyErr_Occurred()) {
Serhiy Storchakac9ea9332017-01-19 18:13:09 +0200122 goto exit;
123 }
124 return_value = math_frexp_impl(module, x);
125
126exit:
127 return return_value;
128}
129
130PyDoc_STRVAR(math_ldexp__doc__,
131"ldexp($module, x, i, /)\n"
132"--\n"
133"\n"
134"Return x * (2**i).\n"
135"\n"
136"This is essentially the inverse of frexp().");
137
138#define MATH_LDEXP_METHODDEF \
Serhiy Storchaka4a934d42018-11-27 11:27:36 +0200139 {"ldexp", (PyCFunction)(void(*)(void))math_ldexp, METH_FASTCALL, math_ldexp__doc__},
Serhiy Storchakac9ea9332017-01-19 18:13:09 +0200140
141static PyObject *
142math_ldexp_impl(PyObject *module, double x, PyObject *i);
143
144static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +0200145math_ldexp(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
Serhiy Storchakac9ea9332017-01-19 18:13:09 +0200146{
147 PyObject *return_value = NULL;
148 double x;
149 PyObject *i;
150
Serhiy Storchaka4fa95912019-01-11 16:01:14 +0200151 if (!_PyArg_CheckPositional("ldexp", nargs, 2, 2)) {
Serhiy Storchakac9ea9332017-01-19 18:13:09 +0200152 goto exit;
153 }
Serhiy Storchaka4fa95912019-01-11 16:01:14 +0200154 x = PyFloat_AsDouble(args[0]);
155 if (PyErr_Occurred()) {
156 goto exit;
157 }
158 i = args[1];
Serhiy Storchakac9ea9332017-01-19 18:13:09 +0200159 return_value = math_ldexp_impl(module, x, i);
160
161exit:
162 return return_value;
163}
164
165PyDoc_STRVAR(math_modf__doc__,
166"modf($module, x, /)\n"
167"--\n"
168"\n"
169"Return the fractional and integer parts of x.\n"
170"\n"
171"Both results carry the sign of x and are floats.");
172
173#define MATH_MODF_METHODDEF \
174 {"modf", (PyCFunction)math_modf, METH_O, math_modf__doc__},
175
176static PyObject *
177math_modf_impl(PyObject *module, double x);
178
179static PyObject *
180math_modf(PyObject *module, PyObject *arg)
181{
182 PyObject *return_value = NULL;
183 double x;
184
Serhiy Storchaka32d96a22018-12-25 13:23:47 +0200185 x = PyFloat_AsDouble(arg);
186 if (PyErr_Occurred()) {
Serhiy Storchakac9ea9332017-01-19 18:13:09 +0200187 goto exit;
188 }
189 return_value = math_modf_impl(module, x);
190
191exit:
192 return return_value;
193}
194
195PyDoc_STRVAR(math_log__doc__,
196"log(x, [base=math.e])\n"
197"Return the logarithm of x to the given base.\n"
198"\n"
199"If the base not specified, returns the natural logarithm (base e) of x.");
200
201#define MATH_LOG_METHODDEF \
202 {"log", (PyCFunction)math_log, METH_VARARGS, math_log__doc__},
203
204static PyObject *
205math_log_impl(PyObject *module, PyObject *x, int group_right_1,
206 PyObject *base);
207
208static PyObject *
209math_log(PyObject *module, PyObject *args)
210{
211 PyObject *return_value = NULL;
212 PyObject *x;
213 int group_right_1 = 0;
214 PyObject *base = NULL;
215
216 switch (PyTuple_GET_SIZE(args)) {
217 case 1:
218 if (!PyArg_ParseTuple(args, "O:log", &x)) {
219 goto exit;
220 }
221 break;
222 case 2:
223 if (!PyArg_ParseTuple(args, "OO:log", &x, &base)) {
224 goto exit;
225 }
226 group_right_1 = 1;
227 break;
228 default:
229 PyErr_SetString(PyExc_TypeError, "math.log requires 1 to 2 arguments");
230 goto exit;
231 }
232 return_value = math_log_impl(module, x, group_right_1, base);
233
234exit:
235 return return_value;
236}
237
238PyDoc_STRVAR(math_log2__doc__,
239"log2($module, x, /)\n"
240"--\n"
241"\n"
242"Return the base 2 logarithm of x.");
243
244#define MATH_LOG2_METHODDEF \
245 {"log2", (PyCFunction)math_log2, METH_O, math_log2__doc__},
246
247PyDoc_STRVAR(math_log10__doc__,
248"log10($module, x, /)\n"
249"--\n"
250"\n"
251"Return the base 10 logarithm of x.");
252
253#define MATH_LOG10_METHODDEF \
254 {"log10", (PyCFunction)math_log10, METH_O, math_log10__doc__},
255
256PyDoc_STRVAR(math_fmod__doc__,
257"fmod($module, x, y, /)\n"
258"--\n"
259"\n"
260"Return fmod(x, y), according to platform C.\n"
261"\n"
262"x % y may differ.");
263
264#define MATH_FMOD_METHODDEF \
Serhiy Storchaka4a934d42018-11-27 11:27:36 +0200265 {"fmod", (PyCFunction)(void(*)(void))math_fmod, METH_FASTCALL, math_fmod__doc__},
Serhiy Storchakac9ea9332017-01-19 18:13:09 +0200266
267static PyObject *
268math_fmod_impl(PyObject *module, double x, double y);
269
270static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +0200271math_fmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
Serhiy Storchakac9ea9332017-01-19 18:13:09 +0200272{
273 PyObject *return_value = NULL;
274 double x;
275 double y;
276
Serhiy Storchaka4fa95912019-01-11 16:01:14 +0200277 if (!_PyArg_CheckPositional("fmod", nargs, 2, 2)) {
278 goto exit;
279 }
280 x = PyFloat_AsDouble(args[0]);
281 if (PyErr_Occurred()) {
282 goto exit;
283 }
284 y = PyFloat_AsDouble(args[1]);
285 if (PyErr_Occurred()) {
Serhiy Storchakac9ea9332017-01-19 18:13:09 +0200286 goto exit;
287 }
288 return_value = math_fmod_impl(module, x, y);
289
290exit:
291 return return_value;
292}
293
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700294PyDoc_STRVAR(math_dist__doc__,
295"dist($module, p, q, /)\n"
296"--\n"
297"\n"
298"Return the Euclidean distance between two points p and q.\n"
299"\n"
Raymond Hettinger6b5f1b42019-07-27 14:04:29 -0700300"The points should be specified as sequences (or iterables) of\n"
301"coordinates. Both inputs must have the same dimension.\n"
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700302"\n"
303"Roughly equivalent to:\n"
304" sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))");
305
306#define MATH_DIST_METHODDEF \
Serhiy Storchaka4a934d42018-11-27 11:27:36 +0200307 {"dist", (PyCFunction)(void(*)(void))math_dist, METH_FASTCALL, math_dist__doc__},
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700308
309static PyObject *
310math_dist_impl(PyObject *module, PyObject *p, PyObject *q);
311
312static PyObject *
313math_dist(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
314{
315 PyObject *return_value = NULL;
316 PyObject *p;
317 PyObject *q;
318
Serhiy Storchaka2a39d252019-01-11 18:01:42 +0200319 if (!_PyArg_CheckPositional("dist", nargs, 2, 2)) {
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700320 goto exit;
321 }
Serhiy Storchaka2a39d252019-01-11 18:01:42 +0200322 p = args[0];
323 q = args[1];
Raymond Hettinger9c18b1a2018-07-31 00:45:49 -0700324 return_value = math_dist_impl(module, p, q);
325
326exit:
327 return return_value;
328}
329
Serhiy Storchakac9ea9332017-01-19 18:13:09 +0200330PyDoc_STRVAR(math_pow__doc__,
331"pow($module, x, y, /)\n"
332"--\n"
333"\n"
334"Return x**y (x to the power of y).");
335
336#define MATH_POW_METHODDEF \
Serhiy Storchaka4a934d42018-11-27 11:27:36 +0200337 {"pow", (PyCFunction)(void(*)(void))math_pow, METH_FASTCALL, math_pow__doc__},
Serhiy Storchakac9ea9332017-01-19 18:13:09 +0200338
339static PyObject *
340math_pow_impl(PyObject *module, double x, double y);
341
342static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +0200343math_pow(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
Serhiy Storchakac9ea9332017-01-19 18:13:09 +0200344{
345 PyObject *return_value = NULL;
346 double x;
347 double y;
348
Serhiy Storchaka4fa95912019-01-11 16:01:14 +0200349 if (!_PyArg_CheckPositional("pow", nargs, 2, 2)) {
350 goto exit;
351 }
352 x = PyFloat_AsDouble(args[0]);
353 if (PyErr_Occurred()) {
354 goto exit;
355 }
356 y = PyFloat_AsDouble(args[1]);
357 if (PyErr_Occurred()) {
Serhiy Storchakac9ea9332017-01-19 18:13:09 +0200358 goto exit;
359 }
360 return_value = math_pow_impl(module, x, y);
361
362exit:
363 return return_value;
364}
365
366PyDoc_STRVAR(math_degrees__doc__,
367"degrees($module, x, /)\n"
368"--\n"
369"\n"
370"Convert angle x from radians to degrees.");
371
372#define MATH_DEGREES_METHODDEF \
373 {"degrees", (PyCFunction)math_degrees, METH_O, math_degrees__doc__},
374
375static PyObject *
376math_degrees_impl(PyObject *module, double x);
377
378static PyObject *
379math_degrees(PyObject *module, PyObject *arg)
380{
381 PyObject *return_value = NULL;
382 double x;
383
Serhiy Storchaka32d96a22018-12-25 13:23:47 +0200384 x = PyFloat_AsDouble(arg);
385 if (PyErr_Occurred()) {
Serhiy Storchakac9ea9332017-01-19 18:13:09 +0200386 goto exit;
387 }
388 return_value = math_degrees_impl(module, x);
389
390exit:
391 return return_value;
392}
393
394PyDoc_STRVAR(math_radians__doc__,
395"radians($module, x, /)\n"
396"--\n"
397"\n"
398"Convert angle x from degrees to radians.");
399
400#define MATH_RADIANS_METHODDEF \
401 {"radians", (PyCFunction)math_radians, METH_O, math_radians__doc__},
402
403static PyObject *
404math_radians_impl(PyObject *module, double x);
405
406static PyObject *
407math_radians(PyObject *module, PyObject *arg)
408{
409 PyObject *return_value = NULL;
410 double x;
411
Serhiy Storchaka32d96a22018-12-25 13:23:47 +0200412 x = PyFloat_AsDouble(arg);
413 if (PyErr_Occurred()) {
Serhiy Storchakac9ea9332017-01-19 18:13:09 +0200414 goto exit;
415 }
416 return_value = math_radians_impl(module, x);
417
418exit:
419 return return_value;
420}
421
422PyDoc_STRVAR(math_isfinite__doc__,
423"isfinite($module, x, /)\n"
424"--\n"
425"\n"
426"Return True if x is neither an infinity nor a NaN, and False otherwise.");
427
428#define MATH_ISFINITE_METHODDEF \
429 {"isfinite", (PyCFunction)math_isfinite, METH_O, math_isfinite__doc__},
430
431static PyObject *
432math_isfinite_impl(PyObject *module, double x);
433
434static PyObject *
435math_isfinite(PyObject *module, PyObject *arg)
436{
437 PyObject *return_value = NULL;
438 double x;
439
Serhiy Storchaka32d96a22018-12-25 13:23:47 +0200440 x = PyFloat_AsDouble(arg);
441 if (PyErr_Occurred()) {
Serhiy Storchakac9ea9332017-01-19 18:13:09 +0200442 goto exit;
443 }
444 return_value = math_isfinite_impl(module, x);
445
446exit:
447 return return_value;
448}
449
450PyDoc_STRVAR(math_isnan__doc__,
451"isnan($module, x, /)\n"
452"--\n"
453"\n"
454"Return True if x is a NaN (not a number), and False otherwise.");
455
456#define MATH_ISNAN_METHODDEF \
457 {"isnan", (PyCFunction)math_isnan, METH_O, math_isnan__doc__},
458
459static PyObject *
460math_isnan_impl(PyObject *module, double x);
461
462static PyObject *
463math_isnan(PyObject *module, PyObject *arg)
464{
465 PyObject *return_value = NULL;
466 double x;
467
Serhiy Storchaka32d96a22018-12-25 13:23:47 +0200468 x = PyFloat_AsDouble(arg);
469 if (PyErr_Occurred()) {
Serhiy Storchakac9ea9332017-01-19 18:13:09 +0200470 goto exit;
471 }
472 return_value = math_isnan_impl(module, x);
473
474exit:
475 return return_value;
476}
477
478PyDoc_STRVAR(math_isinf__doc__,
479"isinf($module, x, /)\n"
480"--\n"
481"\n"
482"Return True if x is a positive or negative infinity, and False otherwise.");
483
484#define MATH_ISINF_METHODDEF \
485 {"isinf", (PyCFunction)math_isinf, METH_O, math_isinf__doc__},
486
487static PyObject *
488math_isinf_impl(PyObject *module, double x);
489
490static PyObject *
491math_isinf(PyObject *module, PyObject *arg)
492{
493 PyObject *return_value = NULL;
494 double x;
495
Serhiy Storchaka32d96a22018-12-25 13:23:47 +0200496 x = PyFloat_AsDouble(arg);
497 if (PyErr_Occurred()) {
Serhiy Storchakac9ea9332017-01-19 18:13:09 +0200498 goto exit;
499 }
500 return_value = math_isinf_impl(module, x);
501
502exit:
503 return return_value;
504}
505
506PyDoc_STRVAR(math_isclose__doc__,
507"isclose($module, /, a, b, *, rel_tol=1e-09, abs_tol=0.0)\n"
508"--\n"
509"\n"
510"Determine whether two floating point numbers are close in value.\n"
511"\n"
512" rel_tol\n"
513" maximum difference for being considered \"close\", relative to the\n"
514" magnitude of the input values\n"
515" abs_tol\n"
516" maximum difference for being considered \"close\", regardless of the\n"
517" magnitude of the input values\n"
518"\n"
519"Return True if a is close in value to b, and False otherwise.\n"
520"\n"
521"For the values to be considered close, the difference between them\n"
522"must be smaller than at least one of the tolerances.\n"
523"\n"
524"-inf, inf and NaN behave similarly to the IEEE 754 Standard. That\n"
525"is, NaN is not close to anything, even itself. inf and -inf are\n"
526"only close to themselves.");
527
528#define MATH_ISCLOSE_METHODDEF \
Serhiy Storchaka4a934d42018-11-27 11:27:36 +0200529 {"isclose", (PyCFunction)(void(*)(void))math_isclose, METH_FASTCALL|METH_KEYWORDS, math_isclose__doc__},
Serhiy Storchakac9ea9332017-01-19 18:13:09 +0200530
531static int
532math_isclose_impl(PyObject *module, double a, double b, double rel_tol,
533 double abs_tol);
534
535static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +0200536math_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
Serhiy Storchakac9ea9332017-01-19 18:13:09 +0200537{
538 PyObject *return_value = NULL;
539 static const char * const _keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL};
Serhiy Storchaka31913912019-03-14 10:32:22 +0200540 static _PyArg_Parser _parser = {NULL, _keywords, "isclose", 0};
541 PyObject *argsbuf[4];
542 Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
Serhiy Storchakac9ea9332017-01-19 18:13:09 +0200543 double a;
544 double b;
545 double rel_tol = 1e-09;
546 double abs_tol = 0.0;
547 int _return_value;
548
Serhiy Storchaka31913912019-03-14 10:32:22 +0200549 args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf);
550 if (!args) {
Serhiy Storchakac9ea9332017-01-19 18:13:09 +0200551 goto exit;
552 }
Serhiy Storchaka31913912019-03-14 10:32:22 +0200553 a = PyFloat_AsDouble(args[0]);
554 if (PyErr_Occurred()) {
555 goto exit;
556 }
557 b = PyFloat_AsDouble(args[1]);
558 if (PyErr_Occurred()) {
559 goto exit;
560 }
561 if (!noptargs) {
562 goto skip_optional_kwonly;
563 }
564 if (args[2]) {
565 rel_tol = PyFloat_AsDouble(args[2]);
566 if (PyErr_Occurred()) {
567 goto exit;
568 }
569 if (!--noptargs) {
570 goto skip_optional_kwonly;
571 }
572 }
573 abs_tol = PyFloat_AsDouble(args[3]);
574 if (PyErr_Occurred()) {
575 goto exit;
576 }
577skip_optional_kwonly:
Serhiy Storchakac9ea9332017-01-19 18:13:09 +0200578 _return_value = math_isclose_impl(module, a, b, rel_tol, abs_tol);
579 if ((_return_value == -1) && PyErr_Occurred()) {
580 goto exit;
581 }
582 return_value = PyBool_FromLong((long)_return_value);
583
584exit:
585 return return_value;
586}
Pablo Galindobc098512019-02-07 07:04:02 +0000587
588PyDoc_STRVAR(math_prod__doc__,
589"prod($module, iterable, /, *, start=1)\n"
590"--\n"
591"\n"
592"Calculate the product of all the elements in the input iterable.\n"
593"\n"
594"The default start value for the product is 1.\n"
595"\n"
596"When the iterable is empty, return the start value. This function is\n"
597"intended specifically for use with numeric values and may reject\n"
598"non-numeric types.");
599
600#define MATH_PROD_METHODDEF \
601 {"prod", (PyCFunction)(void(*)(void))math_prod, METH_FASTCALL|METH_KEYWORDS, math_prod__doc__},
602
603static PyObject *
604math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start);
605
606static PyObject *
607math_prod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
608{
609 PyObject *return_value = NULL;
610 static const char * const _keywords[] = {"", "start", NULL};
Serhiy Storchaka31913912019-03-14 10:32:22 +0200611 static _PyArg_Parser _parser = {NULL, _keywords, "prod", 0};
612 PyObject *argsbuf[2];
613 Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
Pablo Galindobc098512019-02-07 07:04:02 +0000614 PyObject *iterable;
615 PyObject *start = NULL;
616
Serhiy Storchaka31913912019-03-14 10:32:22 +0200617 args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
618 if (!args) {
Pablo Galindobc098512019-02-07 07:04:02 +0000619 goto exit;
620 }
Serhiy Storchaka31913912019-03-14 10:32:22 +0200621 iterable = args[0];
622 if (!noptargs) {
623 goto skip_optional_kwonly;
624 }
625 start = args[1];
626skip_optional_kwonly:
Pablo Galindobc098512019-02-07 07:04:02 +0000627 return_value = math_prod_impl(module, iterable, start);
628
629exit:
630 return return_value;
631}
Yash Aggarwal4a686502019-06-01 12:51:27 +0530632
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +0300633PyDoc_STRVAR(math_perm__doc__,
Raymond Hettingere119b3d2019-06-08 08:58:11 -0700634"perm($module, n, k=None, /)\n"
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +0300635"--\n"
636"\n"
637"Number of ways to choose k items from n items without repetition and with order.\n"
638"\n"
Raymond Hettinger963eb0f2019-06-04 01:23:06 -0700639"Evaluates to n! / (n - k)! when k <= n and evaluates\n"
640"to zero when k > n.\n"
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +0300641"\n"
Raymond Hettingere119b3d2019-06-08 08:58:11 -0700642"If k is not specified or is None, then k defaults to n\n"
643"and the function returns n!.\n"
644"\n"
Raymond Hettinger963eb0f2019-06-04 01:23:06 -0700645"Raises TypeError if either of the arguments are not integers.\n"
646"Raises ValueError if either of the arguments are negative.");
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +0300647
648#define MATH_PERM_METHODDEF \
649 {"perm", (PyCFunction)(void(*)(void))math_perm, METH_FASTCALL, math_perm__doc__},
650
651static PyObject *
652math_perm_impl(PyObject *module, PyObject *n, PyObject *k);
653
654static PyObject *
655math_perm(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
656{
657 PyObject *return_value = NULL;
658 PyObject *n;
Raymond Hettingere119b3d2019-06-08 08:58:11 -0700659 PyObject *k = Py_None;
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +0300660
Raymond Hettingere119b3d2019-06-08 08:58:11 -0700661 if (!_PyArg_CheckPositional("perm", nargs, 1, 2)) {
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +0300662 goto exit;
663 }
664 n = args[0];
Raymond Hettingere119b3d2019-06-08 08:58:11 -0700665 if (nargs < 2) {
666 goto skip_optional;
667 }
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +0300668 k = args[1];
Raymond Hettingere119b3d2019-06-08 08:58:11 -0700669skip_optional:
Serhiy Storchaka5ae299a2019-06-02 11:16:49 +0300670 return_value = math_perm_impl(module, n, k);
671
672exit:
673 return return_value;
674}
675
Yash Aggarwal4a686502019-06-01 12:51:27 +0530676PyDoc_STRVAR(math_comb__doc__,
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +0300677"comb($module, n, k, /)\n"
Yash Aggarwal4a686502019-06-01 12:51:27 +0530678"--\n"
679"\n"
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +0300680"Number of ways to choose k items from n items without repetition and without order.\n"
Yash Aggarwal4a686502019-06-01 12:51:27 +0530681"\n"
Raymond Hettinger963eb0f2019-06-04 01:23:06 -0700682"Evaluates to n! / (k! * (n - k)!) when k <= n and evaluates\n"
683"to zero when k > n.\n"
Yash Aggarwal4a686502019-06-01 12:51:27 +0530684"\n"
Raymond Hettinger963eb0f2019-06-04 01:23:06 -0700685"Also called the binomial coefficient because it is equivalent\n"
686"to the coefficient of k-th term in polynomial expansion of the\n"
687"expression (1 + x)**n.\n"
688"\n"
689"Raises TypeError if either of the arguments are not integers.\n"
690"Raises ValueError if either of the arguments are negative.");
Yash Aggarwal4a686502019-06-01 12:51:27 +0530691
692#define MATH_COMB_METHODDEF \
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +0300693 {"comb", (PyCFunction)(void(*)(void))math_comb, METH_FASTCALL, math_comb__doc__},
Yash Aggarwal4a686502019-06-01 12:51:27 +0530694
695static PyObject *
696math_comb_impl(PyObject *module, PyObject *n, PyObject *k);
697
698static PyObject *
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +0300699math_comb(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
Yash Aggarwal4a686502019-06-01 12:51:27 +0530700{
701 PyObject *return_value = NULL;
Yash Aggarwal4a686502019-06-01 12:51:27 +0530702 PyObject *n;
703 PyObject *k;
704
Serhiy Storchaka2b843ac2019-06-01 22:09:02 +0300705 if (!_PyArg_CheckPositional("comb", nargs, 2, 2)) {
Yash Aggarwal4a686502019-06-01 12:51:27 +0530706 goto exit;
707 }
708 n = args[0];
Yash Aggarwal4a686502019-06-01 12:51:27 +0530709 k = args[1];
710 return_value = math_comb_impl(module, n, k);
711
712exit:
713 return return_value;
714}
Raymond Hettinger6b5f1b42019-07-27 14:04:29 -0700715/*[clinic end generated code: output=f93cfe13ab2fdb4e input=a9049054013a1b77]*/