1/*[clinic input]
2preserve
3[clinic start generated code]*/
4
5PyDoc_STRVAR(math_ceil__doc__,
6"ceil($module, x, /)\n"
7"--\n"
8"\n"
9"Return the ceiling of x as an Integral.\n"
10"\n"
11"This is the smallest integer >= x.");
12
13#define MATH_CEIL_METHODDEF \
14 {"ceil", (PyCFunction)math_ceil, METH_O, math_ceil__doc__},
15
16PyDoc_STRVAR(math_floor__doc__,
17"floor($module, x, /)\n"
18"--\n"
19"\n"
20"Return the floor of x as an Integral.\n"
21"\n"
22"This is the largest integer <= x.");
23
24#define MATH_FLOOR_METHODDEF \
25 {"floor", (PyCFunction)math_floor, METH_O, math_floor__doc__},
26
27PyDoc_STRVAR(math_fsum__doc__,
28"fsum($module, seq, /)\n"
29"--\n"
30"\n"
31"Return an accurate floating point sum of values in the iterable seq.\n"
32"\n"
33"Assumes IEEE-754 floating point arithmetic.");
34
35#define MATH_FSUM_METHODDEF \
36 {"fsum", (PyCFunction)math_fsum, METH_O, math_fsum__doc__},
37
38PyDoc_STRVAR(math_isqrt__doc__,
39"isqrt($module, n, /)\n"
40"--\n"
41"\n"
42"Return the integer part of the square root of the input.");
43
44#define MATH_ISQRT_METHODDEF \
45 {"isqrt", (PyCFunction)math_isqrt, METH_O, math_isqrt__doc__},
46
47PyDoc_STRVAR(math_factorial__doc__,
48"factorial($module, x, /)\n"
49"--\n"
50"\n"
51"Find x!.\n"
52"\n"
53"Raise a ValueError if x is negative or non-integral.");
54
55#define MATH_FACTORIAL_METHODDEF \
56 {"factorial", (PyCFunction)math_factorial, METH_O, math_factorial__doc__},
57
58PyDoc_STRVAR(math_trunc__doc__,
59"trunc($module, x, /)\n"
60"--\n"
61"\n"
62"Truncates the Real x to the nearest Integral toward 0.\n"
63"\n"
64"Uses the __trunc__ magic method.");
65
66#define MATH_TRUNC_METHODDEF \
67 {"trunc", (PyCFunction)math_trunc, METH_O, math_trunc__doc__},
68
69PyDoc_STRVAR(math_frexp__doc__,
70"frexp($module, x, /)\n"
71"--\n"
72"\n"
73"Return the mantissa and exponent of x, as pair (m, e).\n"
74"\n"
75"m is a float and e is an int, such that x = m * 2.**e.\n"
76"If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0.");
77
78#define MATH_FREXP_METHODDEF \
79 {"frexp", (PyCFunction)math_frexp, METH_O, math_frexp__doc__},
80
81static PyObject *
82math_frexp_impl(PyObject *module, double x);
83
84static PyObject *
85math_frexp(PyObject *module, PyObject *arg)
86{
87 PyObject *return_value = NULL;
88 double x;
89
90 if (PyFloat_CheckExact(arg)) {
91 x = PyFloat_AS_DOUBLE(arg);
92 }
93 else
94 {
95 x = PyFloat_AsDouble(arg);
96 if (x == -1.0 && PyErr_Occurred()) {
97 goto exit;
98 }
99 }
100 return_value = math_frexp_impl(module, x);
101
102exit:
103 return return_value;
104}
105
106PyDoc_STRVAR(math_ldexp__doc__,
107"ldexp($module, x, i, /)\n"
108"--\n"
109"\n"
110"Return x * (2**i).\n"
111"\n"
112"This is essentially the inverse of frexp().");
113
114#define MATH_LDEXP_METHODDEF \
115 {"ldexp", (PyCFunction)(void(*)(void))math_ldexp, METH_FASTCALL, math_ldexp__doc__},
116
117static PyObject *
118math_ldexp_impl(PyObject *module, double x, PyObject *i);
119
120static PyObject *
121math_ldexp(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
122{
123 PyObject *return_value = NULL;
124 double x;
125 PyObject *i;
126
127 if (!_PyArg_CheckPositional("ldexp", nargs, 2, 2)) {
128 goto exit;
129 }
130 if (PyFloat_CheckExact(args[0])) {
131 x = PyFloat_AS_DOUBLE(args[0]);
132 }
133 else
134 {
135 x = PyFloat_AsDouble(args[0]);
136 if (x == -1.0 && PyErr_Occurred()) {
137 goto exit;
138 }
139 }
140 i = args[1];
141 return_value = math_ldexp_impl(module, x, i);
142
143exit:
144 return return_value;
145}
146
147PyDoc_STRVAR(math_modf__doc__,
148"modf($module, x, /)\n"
149"--\n"
150"\n"
151"Return the fractional and integer parts of x.\n"
152"\n"
153"Both results carry the sign of x and are floats.");
154
155#define MATH_MODF_METHODDEF \
156 {"modf", (PyCFunction)math_modf, METH_O, math_modf__doc__},
157
158static PyObject *
159math_modf_impl(PyObject *module, double x);
160
161static PyObject *
162math_modf(PyObject *module, PyObject *arg)
163{
164 PyObject *return_value = NULL;
165 double x;
166
167 if (PyFloat_CheckExact(arg)) {
168 x = PyFloat_AS_DOUBLE(arg);
169 }
170 else
171 {
172 x = PyFloat_AsDouble(arg);
173 if (x == -1.0 && PyErr_Occurred()) {
174 goto exit;
175 }
176 }
177 return_value = math_modf_impl(module, x);
178
179exit:
180 return return_value;
181}
182
183PyDoc_STRVAR(math_log__doc__,
184"log(x, [base=math.e])\n"
185"Return the logarithm of x to the given base.\n"
186"\n"
187"If the base not specified, returns the natural logarithm (base e) of x.");
188
189#define MATH_LOG_METHODDEF \
190 {"log", (PyCFunction)math_log, METH_VARARGS, math_log__doc__},
191
192static PyObject *
193math_log_impl(PyObject *module, PyObject *x, int group_right_1,
194 PyObject *base);
195
196static PyObject *
197math_log(PyObject *module, PyObject *args)
198{
199 PyObject *return_value = NULL;
200 PyObject *x;
201 int group_right_1 = 0;
202 PyObject *base = NULL;
203
204 switch (PyTuple_GET_SIZE(args)) {
205 case 1:
206 if (!PyArg_ParseTuple(args, "O:log", &x)) {
207 goto exit;
208 }
209 break;
210 case 2:
211 if (!PyArg_ParseTuple(args, "OO:log", &x, &base)) {
212 goto exit;
213 }
214 group_right_1 = 1;
215 break;
216 default:
217 PyErr_SetString(PyExc_TypeError, "math.log requires 1 to 2 arguments");
218 goto exit;
219 }
220 return_value = math_log_impl(module, x, group_right_1, base);
221
222exit:
223 return return_value;
224}
225
226PyDoc_STRVAR(math_log2__doc__,
227"log2($module, x, /)\n"
228"--\n"
229"\n"
230"Return the base 2 logarithm of x.");
231
232#define MATH_LOG2_METHODDEF \
233 {"log2", (PyCFunction)math_log2, METH_O, math_log2__doc__},
234
235PyDoc_STRVAR(math_log10__doc__,
236"log10($module, x, /)\n"
237"--\n"
238"\n"
239"Return the base 10 logarithm of x.");
240
241#define MATH_LOG10_METHODDEF \
242 {"log10", (PyCFunction)math_log10, METH_O, math_log10__doc__},
243
244PyDoc_STRVAR(math_fmod__doc__,
245"fmod($module, x, y, /)\n"
246"--\n"
247"\n"
248"Return fmod(x, y), according to platform C.\n"
249"\n"
250"x % y may differ.");
251
252#define MATH_FMOD_METHODDEF \
253 {"fmod", (PyCFunction)(void(*)(void))math_fmod, METH_FASTCALL, math_fmod__doc__},
254
255static PyObject *
256math_fmod_impl(PyObject *module, double x, double y);
257
258static PyObject *
259math_fmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
260{
261 PyObject *return_value = NULL;
262 double x;
263 double y;
264
265 if (!_PyArg_CheckPositional("fmod", nargs, 2, 2)) {
266 goto exit;
267 }
268 if (PyFloat_CheckExact(args[0])) {
269 x = PyFloat_AS_DOUBLE(args[0]);
270 }
271 else
272 {
273 x = PyFloat_AsDouble(args[0]);
274 if (x == -1.0 && PyErr_Occurred()) {
275 goto exit;
276 }
277 }
278 if (PyFloat_CheckExact(args[1])) {
279 y = PyFloat_AS_DOUBLE(args[1]);
280 }
281 else
282 {
283 y = PyFloat_AsDouble(args[1]);
284 if (y == -1.0 && PyErr_Occurred()) {
285 goto exit;
286 }
287 }
288 return_value = math_fmod_impl(module, x, y);
289
290exit:
291 return return_value;
292}
293
294PyDoc_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"
300"The points should be specified as sequences (or iterables) of\n"
301"coordinates. Both inputs must have the same dimension.\n"
302"\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 \
307 {"dist", (PyCFunction)(void(*)(void))math_dist, METH_FASTCALL, math_dist__doc__},
308
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
319 if (!_PyArg_CheckPositional("dist", nargs, 2, 2)) {
320 goto exit;
321 }
322 p = args[0];
323 q = args[1];
324 return_value = math_dist_impl(module, p, q);
325
326exit:
327 return return_value;
328}
329
330PyDoc_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)(void(*)(void))math_pow, METH_FASTCALL, math_pow__doc__},
338
339static PyObject *
340math_pow_impl(PyObject *module, double x, double y);
341
342static PyObject *
343math_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
374exit:
375 return return_value;
376}
377
378PyDoc_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
387static PyObject *
388math_degrees_impl(PyObject *module, double x);
389
390static PyObject *
391math_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
408exit:
409 return return_value;
410}
411
412PyDoc_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
421static PyObject *
422math_radians_impl(PyObject *module, double x);
423
424static PyObject *
425math_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
442exit:
443 return return_value;
444}
445
446PyDoc_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
455static PyObject *
456math_isfinite_impl(PyObject *module, double x);
457
458static PyObject *
459math_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
476exit:
477 return return_value;
478}
479
480PyDoc_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
489static PyObject *
490math_isnan_impl(PyObject *module, double x);
491
492static PyObject *
493math_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
510exit:
511 return return_value;
512}
513
514PyDoc_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
523static PyObject *
524math_isinf_impl(PyObject *module, double x);
525
526static PyObject *
527math_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
544exit:
545 return return_value;
546}
547
548PyDoc_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)(void(*)(void))math_isclose, METH_FASTCALL|METH_KEYWORDS, math_isclose__doc__},
572
573static int
574math_isclose_impl(PyObject *module, double a, double b, double rel_tol,
575 double abs_tol);
576
577static PyObject *
578math_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
579{
580 PyObject *return_value = NULL;
581 static const char * const _keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL};
582 static _PyArg_Parser _parser = {NULL, _keywords, "isclose", 0};
583 PyObject *argsbuf[4];
584 Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
585 double a;
586 double b;
587 double rel_tol = 1e-09;
588 double abs_tol = 0.0;
589 int _return_value;
590
591 args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf);
592 if (!args) {
593 goto exit;
594 }
595 if (PyFloat_CheckExact(args[0])) {
596 a = PyFloat_AS_DOUBLE(args[0]);
597 }
598 else
599 {
600 a = PyFloat_AsDouble(args[0]);
601 if (a == -1.0 && PyErr_Occurred()) {
602 goto exit;
603 }
604 }
605 if (PyFloat_CheckExact(args[1])) {
606 b = PyFloat_AS_DOUBLE(args[1]);
607 }
608 else
609 {
610 b = PyFloat_AsDouble(args[1]);
611 if (b == -1.0 && PyErr_Occurred()) {
612 goto exit;
613 }
614 }
615 if (!noptargs) {
616 goto skip_optional_kwonly;
617 }
618 if (args[2]) {
619 if (PyFloat_CheckExact(args[2])) {
620 rel_tol = PyFloat_AS_DOUBLE(args[2]);
621 }
622 else
623 {
624 rel_tol = PyFloat_AsDouble(args[2]);
625 if (rel_tol == -1.0 && PyErr_Occurred()) {
626 goto exit;
627 }
628 }
629 if (!--noptargs) {
630 goto skip_optional_kwonly;
631 }
632 }
633 if (PyFloat_CheckExact(args[3])) {
634 abs_tol = PyFloat_AS_DOUBLE(args[3]);
635 }
636 else
637 {
638 abs_tol = PyFloat_AsDouble(args[3]);
639 if (abs_tol == -1.0 && PyErr_Occurred()) {
640 goto exit;
641 }
642 }
643skip_optional_kwonly:
644 _return_value = math_isclose_impl(module, a, b, rel_tol, abs_tol);
645 if ((_return_value == -1) && PyErr_Occurred()) {
646 goto exit;
647 }
648 return_value = PyBool_FromLong((long)_return_value);
649
650exit:
651 return return_value;
652}
653
654PyDoc_STRVAR(math_prod__doc__,
655"prod($module, iterable, /, *, start=1)\n"
656"--\n"
657"\n"
658"Calculate the product of all the elements in the input iterable.\n"
659"\n"
660"The default start value for the product is 1.\n"
661"\n"
662"When the iterable is empty, return the start value. This function is\n"
663"intended specifically for use with numeric values and may reject\n"
664"non-numeric types.");
665
666#define MATH_PROD_METHODDEF \
667 {"prod", (PyCFunction)(void(*)(void))math_prod, METH_FASTCALL|METH_KEYWORDS, math_prod__doc__},
668
669static PyObject *
670math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start);
671
672static PyObject *
673math_prod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
674{
675 PyObject *return_value = NULL;
676 static const char * const _keywords[] = {"", "start", NULL};
677 static _PyArg_Parser _parser = {NULL, _keywords, "prod", 0};
678 PyObject *argsbuf[2];
679 Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
680 PyObject *iterable;
681 PyObject *start = NULL;
682
683 args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
684 if (!args) {
685 goto exit;
686 }
687 iterable = args[0];
688 if (!noptargs) {
689 goto skip_optional_kwonly;
690 }
691 start = args[1];
692skip_optional_kwonly:
693 return_value = math_prod_impl(module, iterable, start);
694
695exit:
696 return return_value;
697}
698
699PyDoc_STRVAR(math_perm__doc__,
700"perm($module, n, k=None, /)\n"
701"--\n"
702"\n"
703"Number of ways to choose k items from n items without repetition and with order.\n"
704"\n"
705"Evaluates to n! / (n - k)! when k <= n and evaluates\n"
706"to zero when k > n.\n"
707"\n"
708"If k is not specified or is None, then k defaults to n\n"
709"and the function returns n!.\n"
710"\n"
711"Raises TypeError if either of the arguments are not integers.\n"
712"Raises ValueError if either of the arguments are negative.");
713
714#define MATH_PERM_METHODDEF \
715 {"perm", (PyCFunction)(void(*)(void))math_perm, METH_FASTCALL, math_perm__doc__},
716
717static PyObject *
718math_perm_impl(PyObject *module, PyObject *n, PyObject *k);
719
720static PyObject *
721math_perm(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
722{
723 PyObject *return_value = NULL;
724 PyObject *n;
725 PyObject *k = Py_None;
726
727 if (!_PyArg_CheckPositional("perm", nargs, 1, 2)) {
728 goto exit;
729 }
730 n = args[0];
731 if (nargs < 2) {
732 goto skip_optional;
733 }
734 k = args[1];
735skip_optional:
736 return_value = math_perm_impl(module, n, k);
737
738exit:
739 return return_value;
740}
741
742PyDoc_STRVAR(math_comb__doc__,
743"comb($module, n, k, /)\n"
744"--\n"
745"\n"
746"Number of ways to choose k items from n items without repetition and without order.\n"
747"\n"
748"Evaluates to n! / (k! * (n - k)!) when k <= n and evaluates\n"
749"to zero when k > n.\n"
750"\n"
751"Also called the binomial coefficient because it is equivalent\n"
752"to the coefficient of k-th term in polynomial expansion of the\n"
753"expression (1 + x)**n.\n"
754"\n"
755"Raises TypeError if either of the arguments are not integers.\n"
756"Raises ValueError if either of the arguments are negative.");
757
758#define MATH_COMB_METHODDEF \
759 {"comb", (PyCFunction)(void(*)(void))math_comb, METH_FASTCALL, math_comb__doc__},
760
761static PyObject *
762math_comb_impl(PyObject *module, PyObject *n, PyObject *k);
763
764static PyObject *
765math_comb(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
766{
767 PyObject *return_value = NULL;
768 PyObject *n;
769 PyObject *k;
770
771 if (!_PyArg_CheckPositional("comb", nargs, 2, 2)) {
772 goto exit;
773 }
774 n = args[0];
775 k = args[1];
776 return_value = math_comb_impl(module, n, k);
777
778exit:
779 return return_value;
780}
781
782PyDoc_STRVAR(math_nextafter__doc__,
783"nextafter($module, x, y, /)\n"
784"--\n"
785"\n"
786"Return the next floating-point value after x towards y.");
787
788#define MATH_NEXTAFTER_METHODDEF \
789 {"nextafter", (PyCFunction)(void(*)(void))math_nextafter, METH_FASTCALL, math_nextafter__doc__},
790
791static PyObject *
792math_nextafter_impl(PyObject *module, double x, double y);
793
794static PyObject *
795math_nextafter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
796{
797 PyObject *return_value = NULL;
798 double x;
799 double y;
800
801 if (!_PyArg_CheckPositional("nextafter", nargs, 2, 2)) {
802 goto exit;
803 }
804 if (PyFloat_CheckExact(args[0])) {
805 x = PyFloat_AS_DOUBLE(args[0]);
806 }
807 else
808 {
809 x = PyFloat_AsDouble(args[0]);
810 if (x == -1.0 && PyErr_Occurred()) {
811 goto exit;
812 }
813 }
814 if (PyFloat_CheckExact(args[1])) {
815 y = PyFloat_AS_DOUBLE(args[1]);
816 }
817 else
818 {
819 y = PyFloat_AsDouble(args[1]);
820 if (y == -1.0 && PyErr_Occurred()) {
821 goto exit;
822 }
823 }
824 return_value = math_nextafter_impl(module, x, y);
825
826exit:
827 return return_value;
828}
829
830PyDoc_STRVAR(math_ulp__doc__,
831"ulp($module, x, /)\n"
832"--\n"
833"\n"
834"Return the value of the least significant bit of the float x.");
835
836#define MATH_ULP_METHODDEF \
837 {"ulp", (PyCFunction)math_ulp, METH_O, math_ulp__doc__},
838
839static double
840math_ulp_impl(PyObject *module, double x);
841
842static PyObject *
843math_ulp(PyObject *module, PyObject *arg)
844{
845 PyObject *return_value = NULL;
846 double x;
847 double _return_value;
848
849 if (PyFloat_CheckExact(arg)) {
850 x = PyFloat_AS_DOUBLE(arg);
851 }
852 else
853 {
854 x = PyFloat_AsDouble(arg);
855 if (x == -1.0 && PyErr_Occurred()) {
856 goto exit;
857 }
858 }
859 _return_value = math_ulp_impl(module, x);
860 if ((_return_value == -1.0) && PyErr_Occurred()) {
861 goto exit;
862 }
863 return_value = PyFloat_FromDouble(_return_value);
864
865exit:
866 return return_value;
867}
868/*[clinic end generated code: output=1eae2b3ef19568fa input=a9049054013a1b77]*/
869