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, n, /)\n"
49"--\n"
50"\n"
51"Find n!.\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_CAST(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_CAST(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_CAST(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_CAST(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_CAST(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_CAST(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_CAST(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_CAST(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_CAST(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=965f99dabaa72165 input=a9049054013a1b77]*/
869