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 #include "pycore_modsupport.h" // _PyArg_CheckPositional()
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 *
math_frexp(PyObject * module,PyObject * arg)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 *
math_ldexp(PyObject * module,PyObject * const * args,Py_ssize_t nargs)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 *
math_modf(PyObject * module,PyObject * arg)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_fma__doc__,
208 "fma($module, x, y, z, /)\n"
209 "--\n"
210 "\n"
211 "Fused multiply-add operation.\n"
212 "\n"
213 "Compute (x * y) + z with a single round.");
214
215 #define MATH_FMA_METHODDEF \
216 {"fma", _PyCFunction_CAST(math_fma), METH_FASTCALL, math_fma__doc__},
217
218 static PyObject *
219 math_fma_impl(PyObject *module, double x, double y, double z);
220
221 static PyObject *
math_fma(PyObject * module,PyObject * const * args,Py_ssize_t nargs)222 math_fma(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
223 {
224 PyObject *return_value = NULL;
225 double x;
226 double y;
227 double z;
228
229 if (!_PyArg_CheckPositional("fma", nargs, 3, 3)) {
230 goto exit;
231 }
232 if (PyFloat_CheckExact(args[0])) {
233 x = PyFloat_AS_DOUBLE(args[0]);
234 }
235 else
236 {
237 x = PyFloat_AsDouble(args[0]);
238 if (x == -1.0 && PyErr_Occurred()) {
239 goto exit;
240 }
241 }
242 if (PyFloat_CheckExact(args[1])) {
243 y = PyFloat_AS_DOUBLE(args[1]);
244 }
245 else
246 {
247 y = PyFloat_AsDouble(args[1]);
248 if (y == -1.0 && PyErr_Occurred()) {
249 goto exit;
250 }
251 }
252 if (PyFloat_CheckExact(args[2])) {
253 z = PyFloat_AS_DOUBLE(args[2]);
254 }
255 else
256 {
257 z = PyFloat_AsDouble(args[2]);
258 if (z == -1.0 && PyErr_Occurred()) {
259 goto exit;
260 }
261 }
262 return_value = math_fma_impl(module, x, y, z);
263
264 exit:
265 return return_value;
266 }
267
268 PyDoc_STRVAR(math_fmod__doc__,
269 "fmod($module, x, y, /)\n"
270 "--\n"
271 "\n"
272 "Return fmod(x, y), according to platform C.\n"
273 "\n"
274 "x % y may differ.");
275
276 #define MATH_FMOD_METHODDEF \
277 {"fmod", _PyCFunction_CAST(math_fmod), METH_FASTCALL, math_fmod__doc__},
278
279 static PyObject *
280 math_fmod_impl(PyObject *module, double x, double y);
281
282 static PyObject *
math_fmod(PyObject * module,PyObject * const * args,Py_ssize_t nargs)283 math_fmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
284 {
285 PyObject *return_value = NULL;
286 double x;
287 double y;
288
289 if (!_PyArg_CheckPositional("fmod", nargs, 2, 2)) {
290 goto exit;
291 }
292 if (PyFloat_CheckExact(args[0])) {
293 x = PyFloat_AS_DOUBLE(args[0]);
294 }
295 else
296 {
297 x = PyFloat_AsDouble(args[0]);
298 if (x == -1.0 && PyErr_Occurred()) {
299 goto exit;
300 }
301 }
302 if (PyFloat_CheckExact(args[1])) {
303 y = PyFloat_AS_DOUBLE(args[1]);
304 }
305 else
306 {
307 y = PyFloat_AsDouble(args[1]);
308 if (y == -1.0 && PyErr_Occurred()) {
309 goto exit;
310 }
311 }
312 return_value = math_fmod_impl(module, x, y);
313
314 exit:
315 return return_value;
316 }
317
318 PyDoc_STRVAR(math_dist__doc__,
319 "dist($module, p, q, /)\n"
320 "--\n"
321 "\n"
322 "Return the Euclidean distance between two points p and q.\n"
323 "\n"
324 "The points should be specified as sequences (or iterables) of\n"
325 "coordinates. Both inputs must have the same dimension.\n"
326 "\n"
327 "Roughly equivalent to:\n"
328 " sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))");
329
330 #define MATH_DIST_METHODDEF \
331 {"dist", _PyCFunction_CAST(math_dist), METH_FASTCALL, math_dist__doc__},
332
333 static PyObject *
334 math_dist_impl(PyObject *module, PyObject *p, PyObject *q);
335
336 static PyObject *
math_dist(PyObject * module,PyObject * const * args,Py_ssize_t nargs)337 math_dist(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
338 {
339 PyObject *return_value = NULL;
340 PyObject *p;
341 PyObject *q;
342
343 if (!_PyArg_CheckPositional("dist", nargs, 2, 2)) {
344 goto exit;
345 }
346 p = args[0];
347 q = args[1];
348 return_value = math_dist_impl(module, p, q);
349
350 exit:
351 return return_value;
352 }
353
354 PyDoc_STRVAR(math_sumprod__doc__,
355 "sumprod($module, p, q, /)\n"
356 "--\n"
357 "\n"
358 "Return the sum of products of values from two iterables p and q.\n"
359 "\n"
360 "Roughly equivalent to:\n"
361 "\n"
362 " sum(itertools.starmap(operator.mul, zip(p, q, strict=True)))\n"
363 "\n"
364 "For float and mixed int/float inputs, the intermediate products\n"
365 "and sums are computed with extended precision.");
366
367 #define MATH_SUMPROD_METHODDEF \
368 {"sumprod", _PyCFunction_CAST(math_sumprod), METH_FASTCALL, math_sumprod__doc__},
369
370 static PyObject *
371 math_sumprod_impl(PyObject *module, PyObject *p, PyObject *q);
372
373 static PyObject *
math_sumprod(PyObject * module,PyObject * const * args,Py_ssize_t nargs)374 math_sumprod(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
375 {
376 PyObject *return_value = NULL;
377 PyObject *p;
378 PyObject *q;
379
380 if (!_PyArg_CheckPositional("sumprod", nargs, 2, 2)) {
381 goto exit;
382 }
383 p = args[0];
384 q = args[1];
385 return_value = math_sumprod_impl(module, p, q);
386
387 exit:
388 return return_value;
389 }
390
391 PyDoc_STRVAR(math_pow__doc__,
392 "pow($module, x, y, /)\n"
393 "--\n"
394 "\n"
395 "Return x**y (x to the power of y).");
396
397 #define MATH_POW_METHODDEF \
398 {"pow", _PyCFunction_CAST(math_pow), METH_FASTCALL, math_pow__doc__},
399
400 static PyObject *
401 math_pow_impl(PyObject *module, double x, double y);
402
403 static PyObject *
math_pow(PyObject * module,PyObject * const * args,Py_ssize_t nargs)404 math_pow(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
405 {
406 PyObject *return_value = NULL;
407 double x;
408 double y;
409
410 if (!_PyArg_CheckPositional("pow", nargs, 2, 2)) {
411 goto exit;
412 }
413 if (PyFloat_CheckExact(args[0])) {
414 x = PyFloat_AS_DOUBLE(args[0]);
415 }
416 else
417 {
418 x = PyFloat_AsDouble(args[0]);
419 if (x == -1.0 && PyErr_Occurred()) {
420 goto exit;
421 }
422 }
423 if (PyFloat_CheckExact(args[1])) {
424 y = PyFloat_AS_DOUBLE(args[1]);
425 }
426 else
427 {
428 y = PyFloat_AsDouble(args[1]);
429 if (y == -1.0 && PyErr_Occurred()) {
430 goto exit;
431 }
432 }
433 return_value = math_pow_impl(module, x, y);
434
435 exit:
436 return return_value;
437 }
438
439 PyDoc_STRVAR(math_degrees__doc__,
440 "degrees($module, x, /)\n"
441 "--\n"
442 "\n"
443 "Convert angle x from radians to degrees.");
444
445 #define MATH_DEGREES_METHODDEF \
446 {"degrees", (PyCFunction)math_degrees, METH_O, math_degrees__doc__},
447
448 static PyObject *
449 math_degrees_impl(PyObject *module, double x);
450
451 static PyObject *
math_degrees(PyObject * module,PyObject * arg)452 math_degrees(PyObject *module, PyObject *arg)
453 {
454 PyObject *return_value = NULL;
455 double x;
456
457 if (PyFloat_CheckExact(arg)) {
458 x = PyFloat_AS_DOUBLE(arg);
459 }
460 else
461 {
462 x = PyFloat_AsDouble(arg);
463 if (x == -1.0 && PyErr_Occurred()) {
464 goto exit;
465 }
466 }
467 return_value = math_degrees_impl(module, x);
468
469 exit:
470 return return_value;
471 }
472
473 PyDoc_STRVAR(math_radians__doc__,
474 "radians($module, x, /)\n"
475 "--\n"
476 "\n"
477 "Convert angle x from degrees to radians.");
478
479 #define MATH_RADIANS_METHODDEF \
480 {"radians", (PyCFunction)math_radians, METH_O, math_radians__doc__},
481
482 static PyObject *
483 math_radians_impl(PyObject *module, double x);
484
485 static PyObject *
math_radians(PyObject * module,PyObject * arg)486 math_radians(PyObject *module, PyObject *arg)
487 {
488 PyObject *return_value = NULL;
489 double x;
490
491 if (PyFloat_CheckExact(arg)) {
492 x = PyFloat_AS_DOUBLE(arg);
493 }
494 else
495 {
496 x = PyFloat_AsDouble(arg);
497 if (x == -1.0 && PyErr_Occurred()) {
498 goto exit;
499 }
500 }
501 return_value = math_radians_impl(module, x);
502
503 exit:
504 return return_value;
505 }
506
507 PyDoc_STRVAR(math_isfinite__doc__,
508 "isfinite($module, x, /)\n"
509 "--\n"
510 "\n"
511 "Return True if x is neither an infinity nor a NaN, and False otherwise.");
512
513 #define MATH_ISFINITE_METHODDEF \
514 {"isfinite", (PyCFunction)math_isfinite, METH_O, math_isfinite__doc__},
515
516 static PyObject *
517 math_isfinite_impl(PyObject *module, double x);
518
519 static PyObject *
math_isfinite(PyObject * module,PyObject * arg)520 math_isfinite(PyObject *module, PyObject *arg)
521 {
522 PyObject *return_value = NULL;
523 double x;
524
525 if (PyFloat_CheckExact(arg)) {
526 x = PyFloat_AS_DOUBLE(arg);
527 }
528 else
529 {
530 x = PyFloat_AsDouble(arg);
531 if (x == -1.0 && PyErr_Occurred()) {
532 goto exit;
533 }
534 }
535 return_value = math_isfinite_impl(module, x);
536
537 exit:
538 return return_value;
539 }
540
541 PyDoc_STRVAR(math_isnan__doc__,
542 "isnan($module, x, /)\n"
543 "--\n"
544 "\n"
545 "Return True if x is a NaN (not a number), and False otherwise.");
546
547 #define MATH_ISNAN_METHODDEF \
548 {"isnan", (PyCFunction)math_isnan, METH_O, math_isnan__doc__},
549
550 static PyObject *
551 math_isnan_impl(PyObject *module, double x);
552
553 static PyObject *
math_isnan(PyObject * module,PyObject * arg)554 math_isnan(PyObject *module, PyObject *arg)
555 {
556 PyObject *return_value = NULL;
557 double x;
558
559 if (PyFloat_CheckExact(arg)) {
560 x = PyFloat_AS_DOUBLE(arg);
561 }
562 else
563 {
564 x = PyFloat_AsDouble(arg);
565 if (x == -1.0 && PyErr_Occurred()) {
566 goto exit;
567 }
568 }
569 return_value = math_isnan_impl(module, x);
570
571 exit:
572 return return_value;
573 }
574
575 PyDoc_STRVAR(math_isinf__doc__,
576 "isinf($module, x, /)\n"
577 "--\n"
578 "\n"
579 "Return True if x is a positive or negative infinity, and False otherwise.");
580
581 #define MATH_ISINF_METHODDEF \
582 {"isinf", (PyCFunction)math_isinf, METH_O, math_isinf__doc__},
583
584 static PyObject *
585 math_isinf_impl(PyObject *module, double x);
586
587 static PyObject *
math_isinf(PyObject * module,PyObject * arg)588 math_isinf(PyObject *module, PyObject *arg)
589 {
590 PyObject *return_value = NULL;
591 double x;
592
593 if (PyFloat_CheckExact(arg)) {
594 x = PyFloat_AS_DOUBLE(arg);
595 }
596 else
597 {
598 x = PyFloat_AsDouble(arg);
599 if (x == -1.0 && PyErr_Occurred()) {
600 goto exit;
601 }
602 }
603 return_value = math_isinf_impl(module, x);
604
605 exit:
606 return return_value;
607 }
608
609 PyDoc_STRVAR(math_isclose__doc__,
610 "isclose($module, /, a, b, *, rel_tol=1e-09, abs_tol=0.0)\n"
611 "--\n"
612 "\n"
613 "Determine whether two floating-point numbers are close in value.\n"
614 "\n"
615 " rel_tol\n"
616 " maximum difference for being considered \"close\", relative to the\n"
617 " magnitude of the input values\n"
618 " abs_tol\n"
619 " maximum difference for being considered \"close\", regardless of the\n"
620 " magnitude of the input values\n"
621 "\n"
622 "Return True if a is close in value to b, and False otherwise.\n"
623 "\n"
624 "For the values to be considered close, the difference between them\n"
625 "must be smaller than at least one of the tolerances.\n"
626 "\n"
627 "-inf, inf and NaN behave similarly to the IEEE 754 Standard. That\n"
628 "is, NaN is not close to anything, even itself. inf and -inf are\n"
629 "only close to themselves.");
630
631 #define MATH_ISCLOSE_METHODDEF \
632 {"isclose", _PyCFunction_CAST(math_isclose), METH_FASTCALL|METH_KEYWORDS, math_isclose__doc__},
633
634 static int
635 math_isclose_impl(PyObject *module, double a, double b, double rel_tol,
636 double abs_tol);
637
638 static PyObject *
math_isclose(PyObject * module,PyObject * const * args,Py_ssize_t nargs,PyObject * kwnames)639 math_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
640 {
641 PyObject *return_value = NULL;
642 #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
643
644 #define NUM_KEYWORDS 4
645 static struct {
646 PyGC_Head _this_is_not_used;
647 PyObject_VAR_HEAD
648 PyObject *ob_item[NUM_KEYWORDS];
649 } _kwtuple = {
650 .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
651 .ob_item = { _Py_LATIN1_CHR('a'), _Py_LATIN1_CHR('b'), &_Py_ID(rel_tol), &_Py_ID(abs_tol), },
652 };
653 #undef NUM_KEYWORDS
654 #define KWTUPLE (&_kwtuple.ob_base.ob_base)
655
656 #else // !Py_BUILD_CORE
657 # define KWTUPLE NULL
658 #endif // !Py_BUILD_CORE
659
660 static const char * const _keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL};
661 static _PyArg_Parser _parser = {
662 .keywords = _keywords,
663 .fname = "isclose",
664 .kwtuple = KWTUPLE,
665 };
666 #undef KWTUPLE
667 PyObject *argsbuf[4];
668 Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
669 double a;
670 double b;
671 double rel_tol = 1e-09;
672 double abs_tol = 0.0;
673 int _return_value;
674
675 args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf);
676 if (!args) {
677 goto exit;
678 }
679 if (PyFloat_CheckExact(args[0])) {
680 a = PyFloat_AS_DOUBLE(args[0]);
681 }
682 else
683 {
684 a = PyFloat_AsDouble(args[0]);
685 if (a == -1.0 && PyErr_Occurred()) {
686 goto exit;
687 }
688 }
689 if (PyFloat_CheckExact(args[1])) {
690 b = PyFloat_AS_DOUBLE(args[1]);
691 }
692 else
693 {
694 b = PyFloat_AsDouble(args[1]);
695 if (b == -1.0 && PyErr_Occurred()) {
696 goto exit;
697 }
698 }
699 if (!noptargs) {
700 goto skip_optional_kwonly;
701 }
702 if (args[2]) {
703 if (PyFloat_CheckExact(args[2])) {
704 rel_tol = PyFloat_AS_DOUBLE(args[2]);
705 }
706 else
707 {
708 rel_tol = PyFloat_AsDouble(args[2]);
709 if (rel_tol == -1.0 && PyErr_Occurred()) {
710 goto exit;
711 }
712 }
713 if (!--noptargs) {
714 goto skip_optional_kwonly;
715 }
716 }
717 if (PyFloat_CheckExact(args[3])) {
718 abs_tol = PyFloat_AS_DOUBLE(args[3]);
719 }
720 else
721 {
722 abs_tol = PyFloat_AsDouble(args[3]);
723 if (abs_tol == -1.0 && PyErr_Occurred()) {
724 goto exit;
725 }
726 }
727 skip_optional_kwonly:
728 _return_value = math_isclose_impl(module, a, b, rel_tol, abs_tol);
729 if ((_return_value == -1) && PyErr_Occurred()) {
730 goto exit;
731 }
732 return_value = PyBool_FromLong((long)_return_value);
733
734 exit:
735 return return_value;
736 }
737
738 PyDoc_STRVAR(math_prod__doc__,
739 "prod($module, iterable, /, *, start=1)\n"
740 "--\n"
741 "\n"
742 "Calculate the product of all the elements in the input iterable.\n"
743 "\n"
744 "The default start value for the product is 1.\n"
745 "\n"
746 "When the iterable is empty, return the start value. This function is\n"
747 "intended specifically for use with numeric values and may reject\n"
748 "non-numeric types.");
749
750 #define MATH_PROD_METHODDEF \
751 {"prod", _PyCFunction_CAST(math_prod), METH_FASTCALL|METH_KEYWORDS, math_prod__doc__},
752
753 static PyObject *
754 math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start);
755
756 static PyObject *
math_prod(PyObject * module,PyObject * const * args,Py_ssize_t nargs,PyObject * kwnames)757 math_prod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
758 {
759 PyObject *return_value = NULL;
760 #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
761
762 #define NUM_KEYWORDS 1
763 static struct {
764 PyGC_Head _this_is_not_used;
765 PyObject_VAR_HEAD
766 PyObject *ob_item[NUM_KEYWORDS];
767 } _kwtuple = {
768 .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
769 .ob_item = { &_Py_ID(start), },
770 };
771 #undef NUM_KEYWORDS
772 #define KWTUPLE (&_kwtuple.ob_base.ob_base)
773
774 #else // !Py_BUILD_CORE
775 # define KWTUPLE NULL
776 #endif // !Py_BUILD_CORE
777
778 static const char * const _keywords[] = {"", "start", NULL};
779 static _PyArg_Parser _parser = {
780 .keywords = _keywords,
781 .fname = "prod",
782 .kwtuple = KWTUPLE,
783 };
784 #undef KWTUPLE
785 PyObject *argsbuf[2];
786 Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
787 PyObject *iterable;
788 PyObject *start = NULL;
789
790 args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
791 if (!args) {
792 goto exit;
793 }
794 iterable = args[0];
795 if (!noptargs) {
796 goto skip_optional_kwonly;
797 }
798 start = args[1];
799 skip_optional_kwonly:
800 return_value = math_prod_impl(module, iterable, start);
801
802 exit:
803 return return_value;
804 }
805
806 PyDoc_STRVAR(math_perm__doc__,
807 "perm($module, n, k=None, /)\n"
808 "--\n"
809 "\n"
810 "Number of ways to choose k items from n items without repetition and with order.\n"
811 "\n"
812 "Evaluates to n! / (n - k)! when k <= n and evaluates\n"
813 "to zero when k > n.\n"
814 "\n"
815 "If k is not specified or is None, then k defaults to n\n"
816 "and the function returns n!.\n"
817 "\n"
818 "Raises TypeError if either of the arguments are not integers.\n"
819 "Raises ValueError if either of the arguments are negative.");
820
821 #define MATH_PERM_METHODDEF \
822 {"perm", _PyCFunction_CAST(math_perm), METH_FASTCALL, math_perm__doc__},
823
824 static PyObject *
825 math_perm_impl(PyObject *module, PyObject *n, PyObject *k);
826
827 static PyObject *
math_perm(PyObject * module,PyObject * const * args,Py_ssize_t nargs)828 math_perm(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
829 {
830 PyObject *return_value = NULL;
831 PyObject *n;
832 PyObject *k = Py_None;
833
834 if (!_PyArg_CheckPositional("perm", nargs, 1, 2)) {
835 goto exit;
836 }
837 n = args[0];
838 if (nargs < 2) {
839 goto skip_optional;
840 }
841 k = args[1];
842 skip_optional:
843 return_value = math_perm_impl(module, n, k);
844
845 exit:
846 return return_value;
847 }
848
849 PyDoc_STRVAR(math_comb__doc__,
850 "comb($module, n, k, /)\n"
851 "--\n"
852 "\n"
853 "Number of ways to choose k items from n items without repetition and without order.\n"
854 "\n"
855 "Evaluates to n! / (k! * (n - k)!) when k <= n and evaluates\n"
856 "to zero when k > n.\n"
857 "\n"
858 "Also called the binomial coefficient because it is equivalent\n"
859 "to the coefficient of k-th term in polynomial expansion of the\n"
860 "expression (1 + x)**n.\n"
861 "\n"
862 "Raises TypeError if either of the arguments are not integers.\n"
863 "Raises ValueError if either of the arguments are negative.");
864
865 #define MATH_COMB_METHODDEF \
866 {"comb", _PyCFunction_CAST(math_comb), METH_FASTCALL, math_comb__doc__},
867
868 static PyObject *
869 math_comb_impl(PyObject *module, PyObject *n, PyObject *k);
870
871 static PyObject *
math_comb(PyObject * module,PyObject * const * args,Py_ssize_t nargs)872 math_comb(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
873 {
874 PyObject *return_value = NULL;
875 PyObject *n;
876 PyObject *k;
877
878 if (!_PyArg_CheckPositional("comb", nargs, 2, 2)) {
879 goto exit;
880 }
881 n = args[0];
882 k = args[1];
883 return_value = math_comb_impl(module, n, k);
884
885 exit:
886 return return_value;
887 }
888
889 PyDoc_STRVAR(math_nextafter__doc__,
890 "nextafter($module, x, y, /, *, steps=None)\n"
891 "--\n"
892 "\n"
893 "Return the floating-point value the given number of steps after x towards y.\n"
894 "\n"
895 "If steps is not specified or is None, it defaults to 1.\n"
896 "\n"
897 "Raises a TypeError, if x or y is not a double, or if steps is not an integer.\n"
898 "Raises ValueError if steps is negative.");
899
900 #define MATH_NEXTAFTER_METHODDEF \
901 {"nextafter", _PyCFunction_CAST(math_nextafter), METH_FASTCALL|METH_KEYWORDS, math_nextafter__doc__},
902
903 static PyObject *
904 math_nextafter_impl(PyObject *module, double x, double y, PyObject *steps);
905
906 static PyObject *
math_nextafter(PyObject * module,PyObject * const * args,Py_ssize_t nargs,PyObject * kwnames)907 math_nextafter(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
908 {
909 PyObject *return_value = NULL;
910 #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
911
912 #define NUM_KEYWORDS 1
913 static struct {
914 PyGC_Head _this_is_not_used;
915 PyObject_VAR_HEAD
916 PyObject *ob_item[NUM_KEYWORDS];
917 } _kwtuple = {
918 .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
919 .ob_item = { &_Py_ID(steps), },
920 };
921 #undef NUM_KEYWORDS
922 #define KWTUPLE (&_kwtuple.ob_base.ob_base)
923
924 #else // !Py_BUILD_CORE
925 # define KWTUPLE NULL
926 #endif // !Py_BUILD_CORE
927
928 static const char * const _keywords[] = {"", "", "steps", NULL};
929 static _PyArg_Parser _parser = {
930 .keywords = _keywords,
931 .fname = "nextafter",
932 .kwtuple = KWTUPLE,
933 };
934 #undef KWTUPLE
935 PyObject *argsbuf[3];
936 Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
937 double x;
938 double y;
939 PyObject *steps = Py_None;
940
941 args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf);
942 if (!args) {
943 goto exit;
944 }
945 if (PyFloat_CheckExact(args[0])) {
946 x = PyFloat_AS_DOUBLE(args[0]);
947 }
948 else
949 {
950 x = PyFloat_AsDouble(args[0]);
951 if (x == -1.0 && PyErr_Occurred()) {
952 goto exit;
953 }
954 }
955 if (PyFloat_CheckExact(args[1])) {
956 y = PyFloat_AS_DOUBLE(args[1]);
957 }
958 else
959 {
960 y = PyFloat_AsDouble(args[1]);
961 if (y == -1.0 && PyErr_Occurred()) {
962 goto exit;
963 }
964 }
965 if (!noptargs) {
966 goto skip_optional_kwonly;
967 }
968 steps = args[2];
969 skip_optional_kwonly:
970 return_value = math_nextafter_impl(module, x, y, steps);
971
972 exit:
973 return return_value;
974 }
975
976 PyDoc_STRVAR(math_ulp__doc__,
977 "ulp($module, x, /)\n"
978 "--\n"
979 "\n"
980 "Return the value of the least significant bit of the float x.");
981
982 #define MATH_ULP_METHODDEF \
983 {"ulp", (PyCFunction)math_ulp, METH_O, math_ulp__doc__},
984
985 static double
986 math_ulp_impl(PyObject *module, double x);
987
988 static PyObject *
math_ulp(PyObject * module,PyObject * arg)989 math_ulp(PyObject *module, PyObject *arg)
990 {
991 PyObject *return_value = NULL;
992 double x;
993 double _return_value;
994
995 if (PyFloat_CheckExact(arg)) {
996 x = PyFloat_AS_DOUBLE(arg);
997 }
998 else
999 {
1000 x = PyFloat_AsDouble(arg);
1001 if (x == -1.0 && PyErr_Occurred()) {
1002 goto exit;
1003 }
1004 }
1005 _return_value = math_ulp_impl(module, x);
1006 if ((_return_value == -1.0) && PyErr_Occurred()) {
1007 goto exit;
1008 }
1009 return_value = PyFloat_FromDouble(_return_value);
1010
1011 exit:
1012 return return_value;
1013 }
1014 /*[clinic end generated code: output=755da3b1dbd9e45f input=a9049054013a1b77]*/
1015