• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*[clinic input]
2 preserve
3 [clinic start generated code]*/
4 
5 PyDoc_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    \
12     {"gcd", (PyCFunction)(void(*)(void))math_gcd, METH_FASTCALL, math_gcd__doc__},
13 
14 static PyObject *
15 math_gcd_impl(PyObject *module, PyObject *a, PyObject *b);
16 
17 static PyObject *
math_gcd(PyObject * module,PyObject * const * args,Py_ssize_t nargs)18 math_gcd(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
19 {
20     PyObject *return_value = NULL;
21     PyObject *a;
22     PyObject *b;
23 
24     if (!_PyArg_CheckPositional("gcd", nargs, 2, 2)) {
25         goto exit;
26     }
27     a = args[0];
28     b = args[1];
29     return_value = math_gcd_impl(module, a, b);
30 
31 exit:
32     return return_value;
33 }
34 
35 PyDoc_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 
46 PyDoc_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 
57 PyDoc_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 
68 PyDoc_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 
77 PyDoc_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 
88 PyDoc_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 
99 PyDoc_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 
111 static PyObject *
112 math_frexp_impl(PyObject *module, double x);
113 
114 static PyObject *
math_frexp(PyObject * module,PyObject * arg)115 math_frexp(PyObject *module, PyObject *arg)
116 {
117     PyObject *return_value = NULL;
118     double x;
119 
120     if (PyFloat_CheckExact(arg)) {
121         x = PyFloat_AS_DOUBLE(arg);
122     }
123     else
124     {
125         x = PyFloat_AsDouble(arg);
126         if (x == -1.0 && PyErr_Occurred()) {
127             goto exit;
128         }
129     }
130     return_value = math_frexp_impl(module, x);
131 
132 exit:
133     return return_value;
134 }
135 
136 PyDoc_STRVAR(math_ldexp__doc__,
137 "ldexp($module, x, i, /)\n"
138 "--\n"
139 "\n"
140 "Return x * (2**i).\n"
141 "\n"
142 "This is essentially the inverse of frexp().");
143 
144 #define MATH_LDEXP_METHODDEF    \
145     {"ldexp", (PyCFunction)(void(*)(void))math_ldexp, METH_FASTCALL, math_ldexp__doc__},
146 
147 static PyObject *
148 math_ldexp_impl(PyObject *module, double x, PyObject *i);
149 
150 static PyObject *
math_ldexp(PyObject * module,PyObject * const * args,Py_ssize_t nargs)151 math_ldexp(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
152 {
153     PyObject *return_value = NULL;
154     double x;
155     PyObject *i;
156 
157     if (!_PyArg_CheckPositional("ldexp", nargs, 2, 2)) {
158         goto exit;
159     }
160     if (PyFloat_CheckExact(args[0])) {
161         x = PyFloat_AS_DOUBLE(args[0]);
162     }
163     else
164     {
165         x = PyFloat_AsDouble(args[0]);
166         if (x == -1.0 && PyErr_Occurred()) {
167             goto exit;
168         }
169     }
170     i = args[1];
171     return_value = math_ldexp_impl(module, x, i);
172 
173 exit:
174     return return_value;
175 }
176 
177 PyDoc_STRVAR(math_modf__doc__,
178 "modf($module, x, /)\n"
179 "--\n"
180 "\n"
181 "Return the fractional and integer parts of x.\n"
182 "\n"
183 "Both results carry the sign of x and are floats.");
184 
185 #define MATH_MODF_METHODDEF    \
186     {"modf", (PyCFunction)math_modf, METH_O, math_modf__doc__},
187 
188 static PyObject *
189 math_modf_impl(PyObject *module, double x);
190 
191 static PyObject *
math_modf(PyObject * module,PyObject * arg)192 math_modf(PyObject *module, PyObject *arg)
193 {
194     PyObject *return_value = NULL;
195     double x;
196 
197     if (PyFloat_CheckExact(arg)) {
198         x = PyFloat_AS_DOUBLE(arg);
199     }
200     else
201     {
202         x = PyFloat_AsDouble(arg);
203         if (x == -1.0 && PyErr_Occurred()) {
204             goto exit;
205         }
206     }
207     return_value = math_modf_impl(module, x);
208 
209 exit:
210     return return_value;
211 }
212 
213 PyDoc_STRVAR(math_log__doc__,
214 "log(x, [base=math.e])\n"
215 "Return the logarithm of x to the given base.\n"
216 "\n"
217 "If the base not specified, returns the natural logarithm (base e) of x.");
218 
219 #define MATH_LOG_METHODDEF    \
220     {"log", (PyCFunction)math_log, METH_VARARGS, math_log__doc__},
221 
222 static PyObject *
223 math_log_impl(PyObject *module, PyObject *x, int group_right_1,
224               PyObject *base);
225 
226 static PyObject *
math_log(PyObject * module,PyObject * args)227 math_log(PyObject *module, PyObject *args)
228 {
229     PyObject *return_value = NULL;
230     PyObject *x;
231     int group_right_1 = 0;
232     PyObject *base = NULL;
233 
234     switch (PyTuple_GET_SIZE(args)) {
235         case 1:
236             if (!PyArg_ParseTuple(args, "O:log", &x)) {
237                 goto exit;
238             }
239             break;
240         case 2:
241             if (!PyArg_ParseTuple(args, "OO:log", &x, &base)) {
242                 goto exit;
243             }
244             group_right_1 = 1;
245             break;
246         default:
247             PyErr_SetString(PyExc_TypeError, "math.log requires 1 to 2 arguments");
248             goto exit;
249     }
250     return_value = math_log_impl(module, x, group_right_1, base);
251 
252 exit:
253     return return_value;
254 }
255 
256 PyDoc_STRVAR(math_log2__doc__,
257 "log2($module, x, /)\n"
258 "--\n"
259 "\n"
260 "Return the base 2 logarithm of x.");
261 
262 #define MATH_LOG2_METHODDEF    \
263     {"log2", (PyCFunction)math_log2, METH_O, math_log2__doc__},
264 
265 PyDoc_STRVAR(math_log10__doc__,
266 "log10($module, x, /)\n"
267 "--\n"
268 "\n"
269 "Return the base 10 logarithm of x.");
270 
271 #define MATH_LOG10_METHODDEF    \
272     {"log10", (PyCFunction)math_log10, METH_O, math_log10__doc__},
273 
274 PyDoc_STRVAR(math_fmod__doc__,
275 "fmod($module, x, y, /)\n"
276 "--\n"
277 "\n"
278 "Return fmod(x, y), according to platform C.\n"
279 "\n"
280 "x % y may differ.");
281 
282 #define MATH_FMOD_METHODDEF    \
283     {"fmod", (PyCFunction)(void(*)(void))math_fmod, METH_FASTCALL, math_fmod__doc__},
284 
285 static PyObject *
286 math_fmod_impl(PyObject *module, double x, double y);
287 
288 static PyObject *
math_fmod(PyObject * module,PyObject * const * args,Py_ssize_t nargs)289 math_fmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
290 {
291     PyObject *return_value = NULL;
292     double x;
293     double y;
294 
295     if (!_PyArg_CheckPositional("fmod", nargs, 2, 2)) {
296         goto exit;
297     }
298     if (PyFloat_CheckExact(args[0])) {
299         x = PyFloat_AS_DOUBLE(args[0]);
300     }
301     else
302     {
303         x = PyFloat_AsDouble(args[0]);
304         if (x == -1.0 && PyErr_Occurred()) {
305             goto exit;
306         }
307     }
308     if (PyFloat_CheckExact(args[1])) {
309         y = PyFloat_AS_DOUBLE(args[1]);
310     }
311     else
312     {
313         y = PyFloat_AsDouble(args[1]);
314         if (y == -1.0 && PyErr_Occurred()) {
315             goto exit;
316         }
317     }
318     return_value = math_fmod_impl(module, x, y);
319 
320 exit:
321     return return_value;
322 }
323 
324 PyDoc_STRVAR(math_dist__doc__,
325 "dist($module, p, q, /)\n"
326 "--\n"
327 "\n"
328 "Return the Euclidean distance between two points p and q.\n"
329 "\n"
330 "The points should be specified as sequences (or iterables) of\n"
331 "coordinates.  Both inputs must have the same dimension.\n"
332 "\n"
333 "Roughly equivalent to:\n"
334 "    sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))");
335 
336 #define MATH_DIST_METHODDEF    \
337     {"dist", (PyCFunction)(void(*)(void))math_dist, METH_FASTCALL, math_dist__doc__},
338 
339 static PyObject *
340 math_dist_impl(PyObject *module, PyObject *p, PyObject *q);
341 
342 static PyObject *
math_dist(PyObject * module,PyObject * const * args,Py_ssize_t nargs)343 math_dist(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
344 {
345     PyObject *return_value = NULL;
346     PyObject *p;
347     PyObject *q;
348 
349     if (!_PyArg_CheckPositional("dist", nargs, 2, 2)) {
350         goto exit;
351     }
352     p = args[0];
353     q = args[1];
354     return_value = math_dist_impl(module, p, q);
355 
356 exit:
357     return return_value;
358 }
359 
360 PyDoc_STRVAR(math_pow__doc__,
361 "pow($module, x, y, /)\n"
362 "--\n"
363 "\n"
364 "Return x**y (x to the power of y).");
365 
366 #define MATH_POW_METHODDEF    \
367     {"pow", (PyCFunction)(void(*)(void))math_pow, METH_FASTCALL, math_pow__doc__},
368 
369 static PyObject *
370 math_pow_impl(PyObject *module, double x, double y);
371 
372 static PyObject *
math_pow(PyObject * module,PyObject * const * args,Py_ssize_t nargs)373 math_pow(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
374 {
375     PyObject *return_value = NULL;
376     double x;
377     double y;
378 
379     if (!_PyArg_CheckPositional("pow", nargs, 2, 2)) {
380         goto exit;
381     }
382     if (PyFloat_CheckExact(args[0])) {
383         x = PyFloat_AS_DOUBLE(args[0]);
384     }
385     else
386     {
387         x = PyFloat_AsDouble(args[0]);
388         if (x == -1.0 && PyErr_Occurred()) {
389             goto exit;
390         }
391     }
392     if (PyFloat_CheckExact(args[1])) {
393         y = PyFloat_AS_DOUBLE(args[1]);
394     }
395     else
396     {
397         y = PyFloat_AsDouble(args[1]);
398         if (y == -1.0 && PyErr_Occurred()) {
399             goto exit;
400         }
401     }
402     return_value = math_pow_impl(module, x, y);
403 
404 exit:
405     return return_value;
406 }
407 
408 PyDoc_STRVAR(math_degrees__doc__,
409 "degrees($module, x, /)\n"
410 "--\n"
411 "\n"
412 "Convert angle x from radians to degrees.");
413 
414 #define MATH_DEGREES_METHODDEF    \
415     {"degrees", (PyCFunction)math_degrees, METH_O, math_degrees__doc__},
416 
417 static PyObject *
418 math_degrees_impl(PyObject *module, double x);
419 
420 static PyObject *
math_degrees(PyObject * module,PyObject * arg)421 math_degrees(PyObject *module, PyObject *arg)
422 {
423     PyObject *return_value = NULL;
424     double x;
425 
426     if (PyFloat_CheckExact(arg)) {
427         x = PyFloat_AS_DOUBLE(arg);
428     }
429     else
430     {
431         x = PyFloat_AsDouble(arg);
432         if (x == -1.0 && PyErr_Occurred()) {
433             goto exit;
434         }
435     }
436     return_value = math_degrees_impl(module, x);
437 
438 exit:
439     return return_value;
440 }
441 
442 PyDoc_STRVAR(math_radians__doc__,
443 "radians($module, x, /)\n"
444 "--\n"
445 "\n"
446 "Convert angle x from degrees to radians.");
447 
448 #define MATH_RADIANS_METHODDEF    \
449     {"radians", (PyCFunction)math_radians, METH_O, math_radians__doc__},
450 
451 static PyObject *
452 math_radians_impl(PyObject *module, double x);
453 
454 static PyObject *
math_radians(PyObject * module,PyObject * arg)455 math_radians(PyObject *module, PyObject *arg)
456 {
457     PyObject *return_value = NULL;
458     double x;
459 
460     if (PyFloat_CheckExact(arg)) {
461         x = PyFloat_AS_DOUBLE(arg);
462     }
463     else
464     {
465         x = PyFloat_AsDouble(arg);
466         if (x == -1.0 && PyErr_Occurred()) {
467             goto exit;
468         }
469     }
470     return_value = math_radians_impl(module, x);
471 
472 exit:
473     return return_value;
474 }
475 
476 PyDoc_STRVAR(math_isfinite__doc__,
477 "isfinite($module, x, /)\n"
478 "--\n"
479 "\n"
480 "Return True if x is neither an infinity nor a NaN, and False otherwise.");
481 
482 #define MATH_ISFINITE_METHODDEF    \
483     {"isfinite", (PyCFunction)math_isfinite, METH_O, math_isfinite__doc__},
484 
485 static PyObject *
486 math_isfinite_impl(PyObject *module, double x);
487 
488 static PyObject *
math_isfinite(PyObject * module,PyObject * arg)489 math_isfinite(PyObject *module, PyObject *arg)
490 {
491     PyObject *return_value = NULL;
492     double x;
493 
494     if (PyFloat_CheckExact(arg)) {
495         x = PyFloat_AS_DOUBLE(arg);
496     }
497     else
498     {
499         x = PyFloat_AsDouble(arg);
500         if (x == -1.0 && PyErr_Occurred()) {
501             goto exit;
502         }
503     }
504     return_value = math_isfinite_impl(module, x);
505 
506 exit:
507     return return_value;
508 }
509 
510 PyDoc_STRVAR(math_isnan__doc__,
511 "isnan($module, x, /)\n"
512 "--\n"
513 "\n"
514 "Return True if x is a NaN (not a number), and False otherwise.");
515 
516 #define MATH_ISNAN_METHODDEF    \
517     {"isnan", (PyCFunction)math_isnan, METH_O, math_isnan__doc__},
518 
519 static PyObject *
520 math_isnan_impl(PyObject *module, double x);
521 
522 static PyObject *
math_isnan(PyObject * module,PyObject * arg)523 math_isnan(PyObject *module, PyObject *arg)
524 {
525     PyObject *return_value = NULL;
526     double x;
527 
528     if (PyFloat_CheckExact(arg)) {
529         x = PyFloat_AS_DOUBLE(arg);
530     }
531     else
532     {
533         x = PyFloat_AsDouble(arg);
534         if (x == -1.0 && PyErr_Occurred()) {
535             goto exit;
536         }
537     }
538     return_value = math_isnan_impl(module, x);
539 
540 exit:
541     return return_value;
542 }
543 
544 PyDoc_STRVAR(math_isinf__doc__,
545 "isinf($module, x, /)\n"
546 "--\n"
547 "\n"
548 "Return True if x is a positive or negative infinity, and False otherwise.");
549 
550 #define MATH_ISINF_METHODDEF    \
551     {"isinf", (PyCFunction)math_isinf, METH_O, math_isinf__doc__},
552 
553 static PyObject *
554 math_isinf_impl(PyObject *module, double x);
555 
556 static PyObject *
math_isinf(PyObject * module,PyObject * arg)557 math_isinf(PyObject *module, PyObject *arg)
558 {
559     PyObject *return_value = NULL;
560     double x;
561 
562     if (PyFloat_CheckExact(arg)) {
563         x = PyFloat_AS_DOUBLE(arg);
564     }
565     else
566     {
567         x = PyFloat_AsDouble(arg);
568         if (x == -1.0 && PyErr_Occurred()) {
569             goto exit;
570         }
571     }
572     return_value = math_isinf_impl(module, x);
573 
574 exit:
575     return return_value;
576 }
577 
578 PyDoc_STRVAR(math_isclose__doc__,
579 "isclose($module, /, a, b, *, rel_tol=1e-09, abs_tol=0.0)\n"
580 "--\n"
581 "\n"
582 "Determine whether two floating point numbers are close in value.\n"
583 "\n"
584 "  rel_tol\n"
585 "    maximum difference for being considered \"close\", relative to the\n"
586 "    magnitude of the input values\n"
587 "  abs_tol\n"
588 "    maximum difference for being considered \"close\", regardless of the\n"
589 "    magnitude of the input values\n"
590 "\n"
591 "Return True if a is close in value to b, and False otherwise.\n"
592 "\n"
593 "For the values to be considered close, the difference between them\n"
594 "must be smaller than at least one of the tolerances.\n"
595 "\n"
596 "-inf, inf and NaN behave similarly to the IEEE 754 Standard.  That\n"
597 "is, NaN is not close to anything, even itself.  inf and -inf are\n"
598 "only close to themselves.");
599 
600 #define MATH_ISCLOSE_METHODDEF    \
601     {"isclose", (PyCFunction)(void(*)(void))math_isclose, METH_FASTCALL|METH_KEYWORDS, math_isclose__doc__},
602 
603 static int
604 math_isclose_impl(PyObject *module, double a, double b, double rel_tol,
605                   double abs_tol);
606 
607 static PyObject *
math_isclose(PyObject * module,PyObject * const * args,Py_ssize_t nargs,PyObject * kwnames)608 math_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
609 {
610     PyObject *return_value = NULL;
611     static const char * const _keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL};
612     static _PyArg_Parser _parser = {NULL, _keywords, "isclose", 0};
613     PyObject *argsbuf[4];
614     Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
615     double a;
616     double b;
617     double rel_tol = 1e-09;
618     double abs_tol = 0.0;
619     int _return_value;
620 
621     args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf);
622     if (!args) {
623         goto exit;
624     }
625     if (PyFloat_CheckExact(args[0])) {
626         a = PyFloat_AS_DOUBLE(args[0]);
627     }
628     else
629     {
630         a = PyFloat_AsDouble(args[0]);
631         if (a == -1.0 && PyErr_Occurred()) {
632             goto exit;
633         }
634     }
635     if (PyFloat_CheckExact(args[1])) {
636         b = PyFloat_AS_DOUBLE(args[1]);
637     }
638     else
639     {
640         b = PyFloat_AsDouble(args[1]);
641         if (b == -1.0 && PyErr_Occurred()) {
642             goto exit;
643         }
644     }
645     if (!noptargs) {
646         goto skip_optional_kwonly;
647     }
648     if (args[2]) {
649         if (PyFloat_CheckExact(args[2])) {
650             rel_tol = PyFloat_AS_DOUBLE(args[2]);
651         }
652         else
653         {
654             rel_tol = PyFloat_AsDouble(args[2]);
655             if (rel_tol == -1.0 && PyErr_Occurred()) {
656                 goto exit;
657             }
658         }
659         if (!--noptargs) {
660             goto skip_optional_kwonly;
661         }
662     }
663     if (PyFloat_CheckExact(args[3])) {
664         abs_tol = PyFloat_AS_DOUBLE(args[3]);
665     }
666     else
667     {
668         abs_tol = PyFloat_AsDouble(args[3]);
669         if (abs_tol == -1.0 && PyErr_Occurred()) {
670             goto exit;
671         }
672     }
673 skip_optional_kwonly:
674     _return_value = math_isclose_impl(module, a, b, rel_tol, abs_tol);
675     if ((_return_value == -1) && PyErr_Occurred()) {
676         goto exit;
677     }
678     return_value = PyBool_FromLong((long)_return_value);
679 
680 exit:
681     return return_value;
682 }
683 
684 PyDoc_STRVAR(math_prod__doc__,
685 "prod($module, iterable, /, *, start=1)\n"
686 "--\n"
687 "\n"
688 "Calculate the product of all the elements in the input iterable.\n"
689 "\n"
690 "The default start value for the product is 1.\n"
691 "\n"
692 "When the iterable is empty, return the start value.  This function is\n"
693 "intended specifically for use with numeric values and may reject\n"
694 "non-numeric types.");
695 
696 #define MATH_PROD_METHODDEF    \
697     {"prod", (PyCFunction)(void(*)(void))math_prod, METH_FASTCALL|METH_KEYWORDS, math_prod__doc__},
698 
699 static PyObject *
700 math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start);
701 
702 static PyObject *
math_prod(PyObject * module,PyObject * const * args,Py_ssize_t nargs,PyObject * kwnames)703 math_prod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
704 {
705     PyObject *return_value = NULL;
706     static const char * const _keywords[] = {"", "start", NULL};
707     static _PyArg_Parser _parser = {NULL, _keywords, "prod", 0};
708     PyObject *argsbuf[2];
709     Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
710     PyObject *iterable;
711     PyObject *start = NULL;
712 
713     args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
714     if (!args) {
715         goto exit;
716     }
717     iterable = args[0];
718     if (!noptargs) {
719         goto skip_optional_kwonly;
720     }
721     start = args[1];
722 skip_optional_kwonly:
723     return_value = math_prod_impl(module, iterable, start);
724 
725 exit:
726     return return_value;
727 }
728 
729 PyDoc_STRVAR(math_perm__doc__,
730 "perm($module, n, k=None, /)\n"
731 "--\n"
732 "\n"
733 "Number of ways to choose k items from n items without repetition and with order.\n"
734 "\n"
735 "Evaluates to n! / (n - k)! when k <= n and evaluates\n"
736 "to zero when k > n.\n"
737 "\n"
738 "If k is not specified or is None, then k defaults to n\n"
739 "and the function returns n!.\n"
740 "\n"
741 "Raises TypeError if either of the arguments are not integers.\n"
742 "Raises ValueError if either of the arguments are negative.");
743 
744 #define MATH_PERM_METHODDEF    \
745     {"perm", (PyCFunction)(void(*)(void))math_perm, METH_FASTCALL, math_perm__doc__},
746 
747 static PyObject *
748 math_perm_impl(PyObject *module, PyObject *n, PyObject *k);
749 
750 static PyObject *
math_perm(PyObject * module,PyObject * const * args,Py_ssize_t nargs)751 math_perm(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
752 {
753     PyObject *return_value = NULL;
754     PyObject *n;
755     PyObject *k = Py_None;
756 
757     if (!_PyArg_CheckPositional("perm", nargs, 1, 2)) {
758         goto exit;
759     }
760     n = args[0];
761     if (nargs < 2) {
762         goto skip_optional;
763     }
764     k = args[1];
765 skip_optional:
766     return_value = math_perm_impl(module, n, k);
767 
768 exit:
769     return return_value;
770 }
771 
772 PyDoc_STRVAR(math_comb__doc__,
773 "comb($module, n, k, /)\n"
774 "--\n"
775 "\n"
776 "Number of ways to choose k items from n items without repetition and without order.\n"
777 "\n"
778 "Evaluates to n! / (k! * (n - k)!) when k <= n and evaluates\n"
779 "to zero when k > n.\n"
780 "\n"
781 "Also called the binomial coefficient because it is equivalent\n"
782 "to the coefficient of k-th term in polynomial expansion of the\n"
783 "expression (1 + x)**n.\n"
784 "\n"
785 "Raises TypeError if either of the arguments are not integers.\n"
786 "Raises ValueError if either of the arguments are negative.");
787 
788 #define MATH_COMB_METHODDEF    \
789     {"comb", (PyCFunction)(void(*)(void))math_comb, METH_FASTCALL, math_comb__doc__},
790 
791 static PyObject *
792 math_comb_impl(PyObject *module, PyObject *n, PyObject *k);
793 
794 static PyObject *
math_comb(PyObject * module,PyObject * const * args,Py_ssize_t nargs)795 math_comb(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
796 {
797     PyObject *return_value = NULL;
798     PyObject *n;
799     PyObject *k;
800 
801     if (!_PyArg_CheckPositional("comb", nargs, 2, 2)) {
802         goto exit;
803     }
804     n = args[0];
805     k = args[1];
806     return_value = math_comb_impl(module, n, k);
807 
808 exit:
809     return return_value;
810 }
811 /*[clinic end generated code: output=9a2b3dc91eb9aadd input=a9049054013a1b77]*/
812