1 /*[clinic input]
2 preserve
3 [clinic start generated code]*/
4
5 #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
6 # include "pycore_gc.h" // PyGC_Head
7 # include "pycore_runtime.h" // _Py_ID()
8 #endif
9
10
11 PyDoc_STRVAR(math_ceil__doc__,
12 "ceil($module, x, /)\n"
13 "--\n"
14 "\n"
15 "Return the ceiling of x as an Integral.\n"
16 "\n"
17 "This is the smallest integer >= x.");
18
19 #define MATH_CEIL_METHODDEF \
20 {"ceil", (PyCFunction)math_ceil, METH_O, math_ceil__doc__},
21
22 PyDoc_STRVAR(math_floor__doc__,
23 "floor($module, x, /)\n"
24 "--\n"
25 "\n"
26 "Return the floor of x as an Integral.\n"
27 "\n"
28 "This is the largest integer <= x.");
29
30 #define MATH_FLOOR_METHODDEF \
31 {"floor", (PyCFunction)math_floor, METH_O, math_floor__doc__},
32
33 PyDoc_STRVAR(math_fsum__doc__,
34 "fsum($module, seq, /)\n"
35 "--\n"
36 "\n"
37 "Return an accurate floating point sum of values in the iterable seq.\n"
38 "\n"
39 "Assumes IEEE-754 floating point arithmetic.");
40
41 #define MATH_FSUM_METHODDEF \
42 {"fsum", (PyCFunction)math_fsum, METH_O, math_fsum__doc__},
43
44 PyDoc_STRVAR(math_isqrt__doc__,
45 "isqrt($module, n, /)\n"
46 "--\n"
47 "\n"
48 "Return the integer part of the square root of the input.");
49
50 #define MATH_ISQRT_METHODDEF \
51 {"isqrt", (PyCFunction)math_isqrt, METH_O, math_isqrt__doc__},
52
53 PyDoc_STRVAR(math_factorial__doc__,
54 "factorial($module, n, /)\n"
55 "--\n"
56 "\n"
57 "Find n!.\n"
58 "\n"
59 "Raise a ValueError if x is negative or non-integral.");
60
61 #define MATH_FACTORIAL_METHODDEF \
62 {"factorial", (PyCFunction)math_factorial, METH_O, math_factorial__doc__},
63
64 PyDoc_STRVAR(math_trunc__doc__,
65 "trunc($module, x, /)\n"
66 "--\n"
67 "\n"
68 "Truncates the Real x to the nearest Integral toward 0.\n"
69 "\n"
70 "Uses the __trunc__ magic method.");
71
72 #define MATH_TRUNC_METHODDEF \
73 {"trunc", (PyCFunction)math_trunc, METH_O, math_trunc__doc__},
74
75 PyDoc_STRVAR(math_frexp__doc__,
76 "frexp($module, x, /)\n"
77 "--\n"
78 "\n"
79 "Return the mantissa and exponent of x, as pair (m, e).\n"
80 "\n"
81 "m is a float and e is an int, such that x = m * 2.**e.\n"
82 "If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0.");
83
84 #define MATH_FREXP_METHODDEF \
85 {"frexp", (PyCFunction)math_frexp, METH_O, math_frexp__doc__},
86
87 static PyObject *
88 math_frexp_impl(PyObject *module, double x);
89
90 static PyObject *
91 math_frexp(PyObject *module, PyObject *arg)
92 {
93 PyObject *return_value = NULL;
94 double x;
95
96 if (PyFloat_CheckExact(arg)) {
97 x = PyFloat_AS_DOUBLE(arg);
98 }
99 else
100 {
101 x = PyFloat_AsDouble(arg);
102 if (x == -1.0 && PyErr_Occurred()) {
103 goto exit;
104 }
105 }
106 return_value = math_frexp_impl(module, x);
107
108 exit:
109 return return_value;
110 }
111
112 PyDoc_STRVAR(math_ldexp__doc__,
113 "ldexp($module, x, i, /)\n"
114 "--\n"
115 "\n"
116 "Return x * (2**i).\n"
117 "\n"
118 "This is essentially the inverse of frexp().");
119
120 #define MATH_LDEXP_METHODDEF \
121 {"ldexp", _PyCFunction_CAST(math_ldexp), METH_FASTCALL, math_ldexp__doc__},
122
123 static PyObject *
124 math_ldexp_impl(PyObject *module, double x, PyObject *i);
125
126 static PyObject *
127 math_ldexp(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
128 {
129 PyObject *return_value = NULL;
130 double x;
131 PyObject *i;
132
133 if (!_PyArg_CheckPositional("ldexp", nargs, 2, 2)) {
134 goto exit;
135 }
136 if (PyFloat_CheckExact(args[0])) {
137 x = PyFloat_AS_DOUBLE(args[0]);
138 }
139 else
140 {
141 x = PyFloat_AsDouble(args[0]);
142 if (x == -1.0 && PyErr_Occurred()) {
143 goto exit;
144 }
145 }
146 i = args[1];
147 return_value = math_ldexp_impl(module, x, i);
148
149 exit:
150 return return_value;
151 }
152
153 PyDoc_STRVAR(math_modf__doc__,
154 "modf($module, x, /)\n"
155 "--\n"
156 "\n"
157 "Return the fractional and integer parts of x.\n"
158 "\n"
159 "Both results carry the sign of x and are floats.");
160
161 #define MATH_MODF_METHODDEF \
162 {"modf", (PyCFunction)math_modf, METH_O, math_modf__doc__},
163
164 static PyObject *
165 math_modf_impl(PyObject *module, double x);
166
167 static PyObject *
168 math_modf(PyObject *module, PyObject *arg)
169 {
170 PyObject *return_value = NULL;
171 double x;
172
173 if (PyFloat_CheckExact(arg)) {
174 x = PyFloat_AS_DOUBLE(arg);
175 }
176 else
177 {
178 x = PyFloat_AsDouble(arg);
179 if (x == -1.0 && PyErr_Occurred()) {
180 goto exit;
181 }
182 }
183 return_value = math_modf_impl(module, x);
184
185 exit:
186 return return_value;
187 }
188
189 PyDoc_STRVAR(math_log2__doc__,
190 "log2($module, x, /)\n"
191 "--\n"
192 "\n"
193 "Return the base 2 logarithm of x.");
194
195 #define MATH_LOG2_METHODDEF \
196 {"log2", (PyCFunction)math_log2, METH_O, math_log2__doc__},
197
198 PyDoc_STRVAR(math_log10__doc__,
199 "log10($module, x, /)\n"
200 "--\n"
201 "\n"
202 "Return the base 10 logarithm of x.");
203
204 #define MATH_LOG10_METHODDEF \
205 {"log10", (PyCFunction)math_log10, METH_O, math_log10__doc__},
206
207 PyDoc_STRVAR(math_fmod__doc__,
208 "fmod($module, x, y, /)\n"
209 "--\n"
210 "\n"
211 "Return fmod(x, y), according to platform C.\n"
212 "\n"
213 "x % y may differ.");
214
215 #define MATH_FMOD_METHODDEF \
216 {"fmod", _PyCFunction_CAST(math_fmod), METH_FASTCALL, math_fmod__doc__},
217
218 static PyObject *
219 math_fmod_impl(PyObject *module, double x, double y);
220
221 static PyObject *
222 math_fmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
223 {
224 PyObject *return_value = NULL;
225 double x;
226 double y;
227
228 if (!_PyArg_CheckPositional("fmod", nargs, 2, 2)) {
229 goto exit;
230 }
231 if (PyFloat_CheckExact(args[0])) {
232 x = PyFloat_AS_DOUBLE(args[0]);
233 }
234 else
235 {
236 x = PyFloat_AsDouble(args[0]);
237 if (x == -1.0 && PyErr_Occurred()) {
238 goto exit;
239 }
240 }
241 if (PyFloat_CheckExact(args[1])) {
242 y = PyFloat_AS_DOUBLE(args[1]);
243 }
244 else
245 {
246 y = PyFloat_AsDouble(args[1]);
247 if (y == -1.0 && PyErr_Occurred()) {
248 goto exit;
249 }
250 }
251 return_value = math_fmod_impl(module, x, y);
252
253 exit:
254 return return_value;
255 }
256
257 PyDoc_STRVAR(math_dist__doc__,
258 "dist($module, p, q, /)\n"
259 "--\n"
260 "\n"
261 "Return the Euclidean distance between two points p and q.\n"
262 "\n"
263 "The points should be specified as sequences (or iterables) of\n"
264 "coordinates. Both inputs must have the same dimension.\n"
265 "\n"
266 "Roughly equivalent to:\n"
267 " sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))");
268
269 #define MATH_DIST_METHODDEF \
270 {"dist", _PyCFunction_CAST(math_dist), METH_FASTCALL, math_dist__doc__},
271
272 static PyObject *
273 math_dist_impl(PyObject *module, PyObject *p, PyObject *q);
274
275 static PyObject *
276 math_dist(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
277 {
278 PyObject *return_value = NULL;
279 PyObject *p;
280 PyObject *q;
281
282 if (!_PyArg_CheckPositional("dist", nargs, 2, 2)) {
283 goto exit;
284 }
285 p = args[0];
286 q = args[1];
287 return_value = math_dist_impl(module, p, q);
288
289 exit:
290 return return_value;
291 }
292
293 PyDoc_STRVAR(math_sumprod__doc__,
294 "sumprod($module, p, q, /)\n"
295 "--\n"
296 "\n"
297 "Return the sum of products of values from two iterables p and q.\n"
298 "\n"
299 "Roughly equivalent to:\n"
300 "\n"
301 " sum(itertools.starmap(operator.mul, zip(p, q, strict=True)))\n"
302 "\n"
303 "For float and mixed int/float inputs, the intermediate products\n"
304 "and sums are computed with extended precision.");
305
306 #define MATH_SUMPROD_METHODDEF \
307 {"sumprod", _PyCFunction_CAST(math_sumprod), METH_FASTCALL, math_sumprod__doc__},
308
309 static PyObject *
310 math_sumprod_impl(PyObject *module, PyObject *p, PyObject *q);
311
312 static PyObject *
313 math_sumprod(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
314 {
315 PyObject *return_value = NULL;
316 PyObject *p;
317 PyObject *q;
318
319 if (!_PyArg_CheckPositional("sumprod", nargs, 2, 2)) {
320 goto exit;
321 }
322 p = args[0];
323 q = args[1];
324 return_value = math_sumprod_impl(module, p, q);
325
326 exit:
327 return return_value;
328 }
329
330 PyDoc_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 \
337 {"pow", _PyCFunction_CAST(math_pow), METH_FASTCALL, math_pow__doc__},
338
339 static PyObject *
340 math_pow_impl(PyObject *module, double x, double y);
341
342 static PyObject *
343 math_pow(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
344 {
345 PyObject *return_value = NULL;
346 double x;
347 double y;
348
349 if (!_PyArg_CheckPositional("pow", nargs, 2, 2)) {
350 goto exit;
351 }
352 if (PyFloat_CheckExact(args[0])) {
353 x = PyFloat_AS_DOUBLE(args[0]);
354 }
355 else
356 {
357 x = PyFloat_AsDouble(args[0]);
358 if (x == -1.0 && PyErr_Occurred()) {
359 goto exit;
360 }
361 }
362 if (PyFloat_CheckExact(args[1])) {
363 y = PyFloat_AS_DOUBLE(args[1]);
364 }
365 else
366 {
367 y = PyFloat_AsDouble(args[1]);
368 if (y == -1.0 && PyErr_Occurred()) {
369 goto exit;
370 }
371 }
372 return_value = math_pow_impl(module, x, y);
373
374 exit:
375 return return_value;
376 }
377
378 PyDoc_STRVAR(math_degrees__doc__,
379 "degrees($module, x, /)\n"
380 "--\n"
381 "\n"
382 "Convert angle x from radians to degrees.");
383
384 #define MATH_DEGREES_METHODDEF \
385 {"degrees", (PyCFunction)math_degrees, METH_O, math_degrees__doc__},
386
387 static PyObject *
388 math_degrees_impl(PyObject *module, double x);
389
390 static PyObject *
391 math_degrees(PyObject *module, PyObject *arg)
392 {
393 PyObject *return_value = NULL;
394 double x;
395
396 if (PyFloat_CheckExact(arg)) {
397 x = PyFloat_AS_DOUBLE(arg);
398 }
399 else
400 {
401 x = PyFloat_AsDouble(arg);
402 if (x == -1.0 && PyErr_Occurred()) {
403 goto exit;
404 }
405 }
406 return_value = math_degrees_impl(module, x);
407
408 exit:
409 return return_value;
410 }
411
412 PyDoc_STRVAR(math_radians__doc__,
413 "radians($module, x, /)\n"
414 "--\n"
415 "\n"
416 "Convert angle x from degrees to radians.");
417
418 #define MATH_RADIANS_METHODDEF \
419 {"radians", (PyCFunction)math_radians, METH_O, math_radians__doc__},
420
421 static PyObject *
422 math_radians_impl(PyObject *module, double x);
423
424 static PyObject *
425 math_radians(PyObject *module, PyObject *arg)
426 {
427 PyObject *return_value = NULL;
428 double x;
429
430 if (PyFloat_CheckExact(arg)) {
431 x = PyFloat_AS_DOUBLE(arg);
432 }
433 else
434 {
435 x = PyFloat_AsDouble(arg);
436 if (x == -1.0 && PyErr_Occurred()) {
437 goto exit;
438 }
439 }
440 return_value = math_radians_impl(module, x);
441
442 exit:
443 return return_value;
444 }
445
446 PyDoc_STRVAR(math_isfinite__doc__,
447 "isfinite($module, x, /)\n"
448 "--\n"
449 "\n"
450 "Return True if x is neither an infinity nor a NaN, and False otherwise.");
451
452 #define MATH_ISFINITE_METHODDEF \
453 {"isfinite", (PyCFunction)math_isfinite, METH_O, math_isfinite__doc__},
454
455 static PyObject *
456 math_isfinite_impl(PyObject *module, double x);
457
458 static PyObject *
459 math_isfinite(PyObject *module, PyObject *arg)
460 {
461 PyObject *return_value = NULL;
462 double x;
463
464 if (PyFloat_CheckExact(arg)) {
465 x = PyFloat_AS_DOUBLE(arg);
466 }
467 else
468 {
469 x = PyFloat_AsDouble(arg);
470 if (x == -1.0 && PyErr_Occurred()) {
471 goto exit;
472 }
473 }
474 return_value = math_isfinite_impl(module, x);
475
476 exit:
477 return return_value;
478 }
479
480 PyDoc_STRVAR(math_isnan__doc__,
481 "isnan($module, x, /)\n"
482 "--\n"
483 "\n"
484 "Return True if x is a NaN (not a number), and False otherwise.");
485
486 #define MATH_ISNAN_METHODDEF \
487 {"isnan", (PyCFunction)math_isnan, METH_O, math_isnan__doc__},
488
489 static PyObject *
490 math_isnan_impl(PyObject *module, double x);
491
492 static PyObject *
493 math_isnan(PyObject *module, PyObject *arg)
494 {
495 PyObject *return_value = NULL;
496 double x;
497
498 if (PyFloat_CheckExact(arg)) {
499 x = PyFloat_AS_DOUBLE(arg);
500 }
501 else
502 {
503 x = PyFloat_AsDouble(arg);
504 if (x == -1.0 && PyErr_Occurred()) {
505 goto exit;
506 }
507 }
508 return_value = math_isnan_impl(module, x);
509
510 exit:
511 return return_value;
512 }
513
514 PyDoc_STRVAR(math_isinf__doc__,
515 "isinf($module, x, /)\n"
516 "--\n"
517 "\n"
518 "Return True if x is a positive or negative infinity, and False otherwise.");
519
520 #define MATH_ISINF_METHODDEF \
521 {"isinf", (PyCFunction)math_isinf, METH_O, math_isinf__doc__},
522
523 static PyObject *
524 math_isinf_impl(PyObject *module, double x);
525
526 static PyObject *
527 math_isinf(PyObject *module, PyObject *arg)
528 {
529 PyObject *return_value = NULL;
530 double x;
531
532 if (PyFloat_CheckExact(arg)) {
533 x = PyFloat_AS_DOUBLE(arg);
534 }
535 else
536 {
537 x = PyFloat_AsDouble(arg);
538 if (x == -1.0 && PyErr_Occurred()) {
539 goto exit;
540 }
541 }
542 return_value = math_isinf_impl(module, x);
543
544 exit:
545 return return_value;
546 }
547
548 PyDoc_STRVAR(math_isclose__doc__,
549 "isclose($module, /, a, b, *, rel_tol=1e-09, abs_tol=0.0)\n"
550 "--\n"
551 "\n"
552 "Determine whether two floating point numbers are close in value.\n"
553 "\n"
554 " rel_tol\n"
555 " maximum difference for being considered \"close\", relative to the\n"
556 " magnitude of the input values\n"
557 " abs_tol\n"
558 " maximum difference for being considered \"close\", regardless of the\n"
559 " magnitude of the input values\n"
560 "\n"
561 "Return True if a is close in value to b, and False otherwise.\n"
562 "\n"
563 "For the values to be considered close, the difference between them\n"
564 "must be smaller than at least one of the tolerances.\n"
565 "\n"
566 "-inf, inf and NaN behave similarly to the IEEE 754 Standard. That\n"
567 "is, NaN is not close to anything, even itself. inf and -inf are\n"
568 "only close to themselves.");
569
570 #define MATH_ISCLOSE_METHODDEF \
571 {"isclose", _PyCFunction_CAST(math_isclose), METH_FASTCALL|METH_KEYWORDS, math_isclose__doc__},
572
573 static int
574 math_isclose_impl(PyObject *module, double a, double b, double rel_tol,
575 double abs_tol);
576
577 static PyObject *
578 math_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
579 {
580 PyObject *return_value = NULL;
581 #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
582
583 #define NUM_KEYWORDS 4
584 static struct {
585 PyGC_Head _this_is_not_used;
586 PyObject_VAR_HEAD
587 PyObject *ob_item[NUM_KEYWORDS];
588 } _kwtuple = {
589 .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
590 .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(rel_tol), &_Py_ID(abs_tol), },
591 };
592 #undef NUM_KEYWORDS
593 #define KWTUPLE (&_kwtuple.ob_base.ob_base)
594
595 #else // !Py_BUILD_CORE
596 # define KWTUPLE NULL
597 #endif // !Py_BUILD_CORE
598
599 static const char * const _keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL};
600 static _PyArg_Parser _parser = {
601 .keywords = _keywords,
602 .fname = "isclose",
603 .kwtuple = KWTUPLE,
604 };
605 #undef KWTUPLE
606 PyObject *argsbuf[4];
607 Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
608 double a;
609 double b;
610 double rel_tol = 1e-09;
611 double abs_tol = 0.0;
612 int _return_value;
613
614 args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf);
615 if (!args) {
616 goto exit;
617 }
618 if (PyFloat_CheckExact(args[0])) {
619 a = PyFloat_AS_DOUBLE(args[0]);
620 }
621 else
622 {
623 a = PyFloat_AsDouble(args[0]);
624 if (a == -1.0 && PyErr_Occurred()) {
625 goto exit;
626 }
627 }
628 if (PyFloat_CheckExact(args[1])) {
629 b = PyFloat_AS_DOUBLE(args[1]);
630 }
631 else
632 {
633 b = PyFloat_AsDouble(args[1]);
634 if (b == -1.0 && PyErr_Occurred()) {
635 goto exit;
636 }
637 }
638 if (!noptargs) {
639 goto skip_optional_kwonly;
640 }
641 if (args[2]) {
642 if (PyFloat_CheckExact(args[2])) {
643 rel_tol = PyFloat_AS_DOUBLE(args[2]);
644 }
645 else
646 {
647 rel_tol = PyFloat_AsDouble(args[2]);
648 if (rel_tol == -1.0 && PyErr_Occurred()) {
649 goto exit;
650 }
651 }
652 if (!--noptargs) {
653 goto skip_optional_kwonly;
654 }
655 }
656 if (PyFloat_CheckExact(args[3])) {
657 abs_tol = PyFloat_AS_DOUBLE(args[3]);
658 }
659 else
660 {
661 abs_tol = PyFloat_AsDouble(args[3]);
662 if (abs_tol == -1.0 && PyErr_Occurred()) {
663 goto exit;
664 }
665 }
666 skip_optional_kwonly:
667 _return_value = math_isclose_impl(module, a, b, rel_tol, abs_tol);
668 if ((_return_value == -1) && PyErr_Occurred()) {
669 goto exit;
670 }
671 return_value = PyBool_FromLong((long)_return_value);
672
673 exit:
674 return return_value;
675 }
676
677 PyDoc_STRVAR(math_prod__doc__,
678 "prod($module, iterable, /, *, start=1)\n"
679 "--\n"
680 "\n"
681 "Calculate the product of all the elements in the input iterable.\n"
682 "\n"
683 "The default start value for the product is 1.\n"
684 "\n"
685 "When the iterable is empty, return the start value. This function is\n"
686 "intended specifically for use with numeric values and may reject\n"
687 "non-numeric types.");
688
689 #define MATH_PROD_METHODDEF \
690 {"prod", _PyCFunction_CAST(math_prod), METH_FASTCALL|METH_KEYWORDS, math_prod__doc__},
691
692 static PyObject *
693 math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start);
694
695 static PyObject *
696 math_prod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
697 {
698 PyObject *return_value = NULL;
699 #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
700
701 #define NUM_KEYWORDS 1
702 static struct {
703 PyGC_Head _this_is_not_used;
704 PyObject_VAR_HEAD
705 PyObject *ob_item[NUM_KEYWORDS];
706 } _kwtuple = {
707 .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
708 .ob_item = { &_Py_ID(start), },
709 };
710 #undef NUM_KEYWORDS
711 #define KWTUPLE (&_kwtuple.ob_base.ob_base)
712
713 #else // !Py_BUILD_CORE
714 # define KWTUPLE NULL
715 #endif // !Py_BUILD_CORE
716
717 static const char * const _keywords[] = {"", "start", NULL};
718 static _PyArg_Parser _parser = {
719 .keywords = _keywords,
720 .fname = "prod",
721 .kwtuple = KWTUPLE,
722 };
723 #undef KWTUPLE
724 PyObject *argsbuf[2];
725 Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
726 PyObject *iterable;
727 PyObject *start = NULL;
728
729 args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
730 if (!args) {
731 goto exit;
732 }
733 iterable = args[0];
734 if (!noptargs) {
735 goto skip_optional_kwonly;
736 }
737 start = args[1];
738 skip_optional_kwonly:
739 return_value = math_prod_impl(module, iterable, start);
740
741 exit:
742 return return_value;
743 }
744
745 PyDoc_STRVAR(math_perm__doc__,
746 "perm($module, n, k=None, /)\n"
747 "--\n"
748 "\n"
749 "Number of ways to choose k items from n items without repetition and with order.\n"
750 "\n"
751 "Evaluates to n! / (n - k)! when k <= n and evaluates\n"
752 "to zero when k > n.\n"
753 "\n"
754 "If k is not specified or is None, then k defaults to n\n"
755 "and the function returns n!.\n"
756 "\n"
757 "Raises TypeError if either of the arguments are not integers.\n"
758 "Raises ValueError if either of the arguments are negative.");
759
760 #define MATH_PERM_METHODDEF \
761 {"perm", _PyCFunction_CAST(math_perm), METH_FASTCALL, math_perm__doc__},
762
763 static PyObject *
764 math_perm_impl(PyObject *module, PyObject *n, PyObject *k);
765
766 static PyObject *
767 math_perm(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
768 {
769 PyObject *return_value = NULL;
770 PyObject *n;
771 PyObject *k = Py_None;
772
773 if (!_PyArg_CheckPositional("perm", nargs, 1, 2)) {
774 goto exit;
775 }
776 n = args[0];
777 if (nargs < 2) {
778 goto skip_optional;
779 }
780 k = args[1];
781 skip_optional:
782 return_value = math_perm_impl(module, n, k);
783
784 exit:
785 return return_value;
786 }
787
788 PyDoc_STRVAR(math_comb__doc__,
789 "comb($module, n, k, /)\n"
790 "--\n"
791 "\n"
792 "Number of ways to choose k items from n items without repetition and without order.\n"
793 "\n"
794 "Evaluates to n! / (k! * (n - k)!) when k <= n and evaluates\n"
795 "to zero when k > n.\n"
796 "\n"
797 "Also called the binomial coefficient because it is equivalent\n"
798 "to the coefficient of k-th term in polynomial expansion of the\n"
799 "expression (1 + x)**n.\n"
800 "\n"
801 "Raises TypeError if either of the arguments are not integers.\n"
802 "Raises ValueError if either of the arguments are negative.");
803
804 #define MATH_COMB_METHODDEF \
805 {"comb", _PyCFunction_CAST(math_comb), METH_FASTCALL, math_comb__doc__},
806
807 static PyObject *
808 math_comb_impl(PyObject *module, PyObject *n, PyObject *k);
809
810 static PyObject *
811 math_comb(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
812 {
813 PyObject *return_value = NULL;
814 PyObject *n;
815 PyObject *k;
816
817 if (!_PyArg_CheckPositional("comb", nargs, 2, 2)) {
818 goto exit;
819 }
820 n = args[0];
821 k = args[1];
822 return_value = math_comb_impl(module, n, k);
823
824 exit:
825 return return_value;
826 }
827
828 PyDoc_STRVAR(math_nextafter__doc__,
829 "nextafter($module, x, y, /, *, steps=None)\n"
830 "--\n"
831 "\n"
832 "Return the floating-point value the given number of steps after x towards y.\n"
833 "\n"
834 "If steps is not specified or is None, it defaults to 1.\n"
835 "\n"
836 "Raises a TypeError, if x or y is not a double, or if steps is not an integer.\n"
837 "Raises ValueError if steps is negative.");
838
839 #define MATH_NEXTAFTER_METHODDEF \
840 {"nextafter", _PyCFunction_CAST(math_nextafter), METH_FASTCALL|METH_KEYWORDS, math_nextafter__doc__},
841
842 static PyObject *
843 math_nextafter_impl(PyObject *module, double x, double y, PyObject *steps);
844
845 static PyObject *
846 math_nextafter(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
847 {
848 PyObject *return_value = NULL;
849 #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
850
851 #define NUM_KEYWORDS 1
852 static struct {
853 PyGC_Head _this_is_not_used;
854 PyObject_VAR_HEAD
855 PyObject *ob_item[NUM_KEYWORDS];
856 } _kwtuple = {
857 .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
858 .ob_item = { &_Py_ID(steps), },
859 };
860 #undef NUM_KEYWORDS
861 #define KWTUPLE (&_kwtuple.ob_base.ob_base)
862
863 #else // !Py_BUILD_CORE
864 # define KWTUPLE NULL
865 #endif // !Py_BUILD_CORE
866
867 static const char * const _keywords[] = {"", "", "steps", NULL};
868 static _PyArg_Parser _parser = {
869 .keywords = _keywords,
870 .fname = "nextafter",
871 .kwtuple = KWTUPLE,
872 };
873 #undef KWTUPLE
874 PyObject *argsbuf[3];
875 Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
876 double x;
877 double y;
878 PyObject *steps = Py_None;
879
880 args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf);
881 if (!args) {
882 goto exit;
883 }
884 if (PyFloat_CheckExact(args[0])) {
885 x = PyFloat_AS_DOUBLE(args[0]);
886 }
887 else
888 {
889 x = PyFloat_AsDouble(args[0]);
890 if (x == -1.0 && PyErr_Occurred()) {
891 goto exit;
892 }
893 }
894 if (PyFloat_CheckExact(args[1])) {
895 y = PyFloat_AS_DOUBLE(args[1]);
896 }
897 else
898 {
899 y = PyFloat_AsDouble(args[1]);
900 if (y == -1.0 && PyErr_Occurred()) {
901 goto exit;
902 }
903 }
904 if (!noptargs) {
905 goto skip_optional_kwonly;
906 }
907 steps = args[2];
908 skip_optional_kwonly:
909 return_value = math_nextafter_impl(module, x, y, steps);
910
911 exit:
912 return return_value;
913 }
914
915 PyDoc_STRVAR(math_ulp__doc__,
916 "ulp($module, x, /)\n"
917 "--\n"
918 "\n"
919 "Return the value of the least significant bit of the float x.");
920
921 #define MATH_ULP_METHODDEF \
922 {"ulp", (PyCFunction)math_ulp, METH_O, math_ulp__doc__},
923
924 static double
925 math_ulp_impl(PyObject *module, double x);
926
927 static PyObject *
928 math_ulp(PyObject *module, PyObject *arg)
929 {
930 PyObject *return_value = NULL;
931 double x;
932 double _return_value;
933
934 if (PyFloat_CheckExact(arg)) {
935 x = PyFloat_AS_DOUBLE(arg);
936 }
937 else
938 {
939 x = PyFloat_AsDouble(arg);
940 if (x == -1.0 && PyErr_Occurred()) {
941 goto exit;
942 }
943 }
944 _return_value = math_ulp_impl(module, x);
945 if ((_return_value == -1.0) && PyErr_Occurred()) {
946 goto exit;
947 }
948 return_value = PyFloat_FromDouble(_return_value);
949
950 exit:
951 return return_value;
952 }
953 /*[clinic end generated code: output=91a0357265a2a553 input=a9049054013a1b77]*/